Skip to content

Account for new fully-specified ECDSA and Ed448 COSEAlgorithmIdentifiers #2283

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

Merged
merged 16 commits into from
May 22, 2025

Conversation

emlun
Copy link
Member

@emlun emlun commented Apr 25, 2025

Fixes #2282.

This:

  • Adds a normative recommendation against using the identifiers -9 (ESP256), -51 (ESP384), -52 (ESP512) and -19 (Ed25519), recommending to continue using -7 (ES256), -35 (ES384), -36 (ES512) and -8 (EdDSA) instead.
  • Carries forward the restriction against compressed point format from the ES* algorithms to the new ESP* algorithms.
  • Adds Ed448 test vectors.
  • Changes the -8 (EdDSA) test vectors to using the seed 'packed.EdDSA' and link anchor #sctn-test-vectors-packed-eddsa instead of 'packed.Ed25519' and #sctn-test-vectors-packed-ed25519, in case we want to add test vectors with COSE alg -19 (Ed25519) in the future.

Preview | Diff

@emlun emlun changed the title Update COSEAlgorithmIdentifier examples and recommendations to prefer fully-specified alg IDs Update examples and recommendations to prefer fully-specified COSEAlgorithmIdentifiers Apr 25, 2025
@emlun emlun changed the title Update examples and recommendations to prefer fully-specified COSEAlgorithmIdentifiers Use fully-specified COSEAlgorithmIdentifiers in examples and recommendations Apr 25, 2025
@zacknewman
Copy link
Contributor

Changes must be made for ESP384 and ESP512 as well. For example updating the packed attestations and adding the additional requirement that the compressed point must be used for those algorithms as you have done for ESP256. For example:

Keys with algorithm ESP384 (-48) MUST NOT use the compressed point form.

@nadalin
Copy link
Contributor

nadalin commented Apr 30, 2025

@selfissued can you review ?

@selfissued
Copy link
Contributor

In 16.8 Packed Attestation with ES384 Credential, the private key should be changed to use ESP384 (-48) rather than ES384 (-35).

In 16.9 Packed Attestation with ES512 Credential, the private key should be changed to use ESP512 (-49) rather than ES512 (-36).

Likewise, the other uses of ES256 should be looked at to change to ESP256, for instance in all the other test vectors in 16 Test Vectors.

@emlun emlun added the stat:Blocked Prerequisites are not yet satisfied label May 6, 2025
@emlun
Copy link
Member Author

emlun commented May 6, 2025

@selfissued Thanks, this is resolved in meta-PR #2290 which in turn depends on #2289. I'll mark this PR as blocked waiting on #2289 so we can update the test vectors along with the generator script.

@emlun emlun self-assigned this May 6, 2025
@zacknewman
Copy link
Contributor

As stated, I'm pretty sure we need to add the requirement that the uncompressed points MUST be used for ESP384 and ESP512 just as we have done for ES256, ESP256, ES384, and ES512.

@emlun
Copy link
Member Author

emlun commented May 6, 2025

@zacknewman Thanks, I had fixed this (thanks for pointing it out!) but apparently forgot to push it. Fixed now in 928c668.

index.bs Outdated
1. Keys with algorithm ES384 (-35) MUST specify P-384 (2) as the [=crv=] parameter and MUST NOT use the compressed point form.
1. Keys with algorithm ESP384 (-48) MUST NOT use the compressed point form.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ECDSA with P384 is -35 I think.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-35 is ECDSA with SHA-384 and unspecified curve (this is why WebAuthn adds the restriction to the P-384 curve on line 4340). -48 is the new identifier that fully specifies ECDSA with SHA-384 and curve P-384.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are logically equivalent, I would actually advice against using these new numbers by the RPs.

Older platforms and Older Authenticators do not understand these numbers and will fail when specified with these numbers.

These new numbers do not add any value IMO vs specifying existing values and will confuse RPs and add support costs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, one such unupgradable security keys shows supporting these algos in their getInfo. [{"alg": -7, "type": "public-key"}, {"alg": -8, "type": "public-key"}, {"alg": -35, "type": "public-key"}]. Newer clients may be able to do the translation to older value from newer values, but not every user agent and OS is upgradable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at earlier discussions in the issue. Fallback mechanism is easy to get it wrong. We have spent years to get these values supported across the ecosystem by every RP, user agent and authenticator.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, let's assume that -7 and -9 are equivalent (ECC-P256/SHA256) and -35 and -1001 (some random number for discussion sake) are equivalent (ECC-P384/SHA384).

Let's say

  • Authenticator-1 supports -7 and -1001.
  • Authenticator-2 supports -7 and -35.

RPs Algorithm preferred list of (-35, -7, -1001, -9) will result in Authenticator-1 picking up (ECC-P256/SHA256) and Authenticator-2 picking up (ECC-P384/SHA384), although technically both support (ECC-P256/SHA256) and (ECC-P384/SHA384)

Having two different values with same meaning in a priority list can become tricky and RP needs to be careful.

I am not seeing the benefit of using the newer values. I would recommend that WebAuthn specify that RPs should use older values as we have already reserved curves for those numbers in WebAuthn.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching the conflict! Draft 12 changed the assignment request to -51. Fixed in c129a05.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that there's little value in these particular identifiers (except the addition of Ed448) within the current context of WebAuthn, where we've explicitly patched the ambiguity in the polymorphic identifiers, but these new identifiers are defined for a wider context that covers more than just WebAuthn. In particular, they patch the gap between JOSE and COSE where, for example, the JOSE identifier "ES256" does fully specify "ECDSA with SHA-256 on the P-256 curve" but the "equivalent" COSE identifier -7 does not (evidently to the WebAuthn WG's surprise earlier) specify the curve, only "ECDSA with SHA-256". For other COSE use cases, especially new ones, it makes a lot of sense to be able to fully describe the crypto suite with a single identifier. So the identifiers definitely have merit in the wider context outside WebAuthn.

So in WebAuthn we are faced with a choice, then: should we support these new identifiers, or not?

If we do not, we'll have to declare that our COSEAlgorithmIdentifier parameter only supports a subset of COSEAlgorithmIdentifier values, and continue updating our exclusion list as new identifiers are added to the registry. And it would need to be an exclusion list rather than an allow list, because with an allow list there'd be no point in referring to an external registry in the first place. I don't think this is a good approach. It's already unfortunate that we add the restrictions against compressed point formats, I don't think we should add even more constraints on our interop with COSE.

If we do support the new identifiers (which WebAuthn L1 and L2 do implicitly!), then I agree that it's unfortunate to have values that are semantically equivalent (in our context) but need to be treated as distinct in order to not confuse implementations. But I think that's a lesser problem. Authenticators are incentivized to support both identifiers in case an RP only requests one (including old RPs that only request the old identifier), and RPs are also incentivized to request both identifiers in case an authenticator only supports one (including existing authenticators that only support the old identifier). But as you say, the old values are likely to continue to dominate for the foreseeable future, so it is unlikely that the new values will disadvantage RPs or authenticators that have not or cannot update to support the new values.

To summarize: the new COSE identifiers apply to a wider context than WebAuthn, and I think that making WebAuthn align more with COSE is better than making WebAuthn diverge further from COSE.

Copy link
Contributor

@zacknewman zacknewman May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that COSE is separate from WebAuthn; however it appears to me that this new draft is very much tied to WebAuthn hence why it is happening in cohort. Yes, technically every RP needs to review IANA COSE algorithms every day for eternity to decide if newer values have been added that they want to support; but I'm unsure if dedicated IDs would be added without this draft. As much as the math person in me would love if specs and registries were super rigorous, one has to accept the fact they aren't and in particular there will be things like "de facto" requirements.

For example, I don't think it's a coincidence there already is an explicit COSE ID for ECDSA with SHA-256 using curve secp256k1 and not for the much more common P-256. To me this is due to the fact that ES256 has the "de facto" requirement that crv is P-256. It's nice for specs to make this clear, like WebAuthn does; but in practice it likely doesn't matter much.

To play the game of hypotheticals, in an alternate universe if COSE never defined the somewhat absurd EdDSA ID but instead ED256 and ED512 IDs where the former were defined as EdDSA using SHAKE256 and the latter were defined as EdDSA using SHA-512; then like ES256 has the "de facto" requirement that crv is P-256, these IDs would have also have had "de facto" requirements that crv is edwards448 and edwards25519 respectively. WebAuthn then would have simply explicitly added those requirements. In that universe, I don't think this draft would have been written since the actual motive of adding support for Ed448 wouldn't have existed.

It appears to me the motive was originally "how do we add Ed448" which then changed to "well since we're here, let's go ahead and also add specific IDs for P-256 and company", and I don't think that adds value. The only counter I can come up with is to my above claim

I'm unsure if dedicated IDs would be added without this draft

If one rejects that and is worried a completely separate "process" were to occur that added these more specific IDs, then WebAuthn is in an unfortunate position of not being able to control this which in turn would lead to some indeterminate amount of time between when such IDs were added to IANA and the spec updated to reflect them. By being in control ourselves, we can be sure there is no "gap" between the IANA registry and spec.

I personally don't find that argument that convincing due to the aforementioned "de facto" requirements and the fact that this prophylactic approach seemingly has no end. What if some process were to add ED256 and ED512 as mentioned, shouldn't we add those too just in case? After all, it is inconsistent to have IDs like ES256 which mandate the hashing algorithm but not the curve so shouldn't the same exist for EdDSA? Conversely, perhaps a process adds ECDSA to mirror EdDSA so COSE now has an ID that is both curve and hashing agnostic. Where does this end?

Regardless, my library already supports these new IDs; so it's no skin off my back. I'm simply providing my two cents.

Copy link
Contributor

@zacknewman zacknewman May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, let's assume that -7 and -9 are equivalent (ECC-P256/SHA256) and -35 and -1001 (some random number for discussion sake) are equivalent (ECC-P384/SHA384).

Let's say

* Authenticator-1 supports -7 and -1001.

* Authenticator-2 supports -7 and -35.

RPs Algorithm preferred list of (-35, -7, -1001, -9) will result in Authenticator-1 picking up (ECC-P256/SHA256) and Authenticator-2 picking up (ECC-P384/SHA384), although technically both support (ECC-P256/SHA256) and (ECC-P384/SHA384)

Having two different values with same meaning in a priority list can become tricky and RP needs to be careful.

I am not seeing the benefit of using the newer values. I would recommend that WebAuthn specify that RPs should use older values as we have already reserved curves for those numbers in WebAuthn.

I've made my thoughts clear on this matter, and I believe this is a solution in search of a problem; however if the committee has determined this is how it is to be, then c'est la vie.

One approach to "solve" this problem is to mandate that user agents always add a legacy ID before/after a "new" ID and add the "new" ID before/after a legacy ID iff the list of supported IDs from the RP contains a "new" ID. Terminology could optionally be added to avoid duplicates that would arise from this; however duplicates have always been a possibility. In addition to this, the spec requires that if an RP supports a "new" ID, then they are obligated to also support the legacy ID potentially also requiring that they be treated interchangeably (e.g., if a self attestation signature uses a legacy ID but the attested credential data uses the "new" ID, RPs are required to accept it—assuming the original list of supported IDs provided by the RP contained the "new" ID). We require that authenticators don't treat the IDs interchangeably in the interest of compatibility.

Here there is consistent behavior, we remove the possibility of "weirdness" from the RP by punting the responsibility to user agents (which already has precedent), and things don't break for RPs that only support the legacy IDs.

As far as terminology is concerned, we should avoid words like "equivalent" since both formally and informally it's not quite correct to say they are equivalent. They're only "equivalent" for RPs that support the new IDs, but they're clearly not equivalent for authenticators nor RPs that don't support the new IDs.

To be clear, user agents perform this "algorithm" for each new ID and not for the mere existence of one (e.g., if an RP passes [-19, -7], then the user agent would modify it such that it becomes [-19,-8,-7] (i.e., user agents conservatively add the legacy ID for EdDSA but don't add the "new" ID for ESP256 since the RP only claimed support for the legacy ES256)).

@OR13
Copy link

OR13 commented May 19, 2025

I understand the desire not to use the new algorithms if the existing ones are burned into devices.

If I understand correctly, the existing webauthn behavior is that in cases where an algorithm worked with multiple curves, webauthn chose a curve, and does not support all the curves for that algorithm, is that correct?

In other words, in webauthn:

-7 means ECDSA with SHA256 and P-256 ... this now has an official name ESP256
-8 means EdDSA with Ed25519 ... this now has an official name Ed25519
...

Just for my own clarity are there any hardware devices out there that use -7 with a curve other than P-256?

In other words, does webauthn make use of the "feature" that -7 works with P-384 and P-521, or does it just ignore that possibility, and assume that -7 is always with P-256? (and my webauthn, I really mean devices that can't be updated, as opposed to the spec itself)

@akshayku
Copy link
Contributor

If I understand correctly, the existing webauthn behavior is that in cases where an algorithm worked with multiple curves, webauthn chose a curve, and does not support all the curves for that algorithm, is that correct?

Yes

Just for my own clarity are there any hardware devices out there that use -7 with a curve other than P-256?

No. AFAIK from over the years.

In other words, does webauthn make use of the "feature" that -7 works with P-384 and P-521, or does it just ignore that possibility, and assume that -7 is always with P-256? (and my webauthn, I really mean devices that can't be updated, as opposed to the spec itself)

We always assume that -7 is ECDSA with P-256. Similarly with others (-8, -35, -36). We have put below descriptions in the spec.

Keys with algorithm ES256 (-7) MUST specify P-256 (1) as the crv parameter and MUST NOT use the compressed point form.

Keys with algorithm ES384 (-35) MUST specify P-384 (2) as the crv parameter and MUST NOT use the compressed point form.

Keys with algorithm ES512 (-36) MUST specify P-521 (3) as the crv parameter and MUST NOT use the compressed point form.

Keys with algorithm EdDSA (-8) MUST specify Ed25519 (6) as the crv parameter. (These always use a compressed form in COSE.)

@emlun
Copy link
Member Author

emlun commented May 20, 2025

@akshayku Ok, but I don't understand what part of this PR would mean more work for any implementations? We are not replacing the old IDs, only adding the new ones to the set of recommended arguments.

  • Current implementations - of authenticators, of clients and of RPs - that only support/request the old IDs will continue to work with the old identifiers.
  • New implementations that support/request both IDs will work with both.
  • New RP implementations that request only the new IDs will not work with current authenticator implementations that only support the old IDs, so they are incentivized to also request the old IDs.
    • Consequently, existing authenticator implementations do not need to update (even in new versions) and can continue supporting only the old IDs if they wish.
  • New authenticator implementations that support only the new IDs will not work with current RP implementations that only request the old IDs, so they are incentivized to also support the old IDs.
    • Consequently, existing RP implementations do not need to update (even in new versions) and can continue requesting only the old IDs if they wish.

So I agree, we're not going to realistically eliminate the old IDs short of a complete ecosystem-wide migration to PQC/etc. But eliminating the old IDs was never a goal either, so I don't see how that is a problem?

Note also that the new IDs will be available for RPs to request and for authenticators to implement regardless of whether we make any change to WebAuthn. The COSEAlgorithmIdentifiers are registered, and WebAuthn L1 and L2 allow any COSEAlgorithmIdentifier to be used. WebAuthn L3 will too unless we explicitly forbid these specific values (which would in my opinion be worse). All this PR does is inform RPs of this new reality: that for maximum compatibility they should request both the old and new IDs (well ok, it does also carry the format restriction on from ES* to ESP*, but that is not what introduces the new alg IDs).

@emlun
Copy link
Member Author

emlun commented May 20, 2025

Hm, maybe I should also include client implementers in the breakdown 🙂

  • Current client implementations whose getPublicKey() supports only the old IDs will continue to work with current RP/authenticator implementations using the old IDs.
  • New RP implementations requesting the new IDs will not be able to use getPublicKey() for new IDs in clients that do not support them, but that is to be expected when using new features.
    • Consequently, RPs are incentivized to either not use getPublicKey() or to continue using the old IDs if they need to use getPublicKey().
    • Consequently, current client implementations do not need to update (even in new versions) to support the new IDs in getPublicKey(). (Unless we make that mandatory in L4, of course.)

Or is this outlook too naive?

@akshayku
Copy link
Contributor

akshayku commented May 20, 2025

@akshayku Ok, but I don't understand what part of this PR would mean more work for any implementations? We are not replacing the old IDs, only adding the new ones to the set of recommended arguments.

Adding it to the WebAuthn means that we are endorsing those new algorithms for WebAuthn. Some algorithms just being registered as COSEAlgorithmIdentifier does not necessarily means that it works in WebAuthn across browser/OS/Authenticator. There are many more COSEAlgorithmIdentifier that does not work for WebAuthn. And I think, Realisticly, the current state is that only algorithms mentioned in the webAuthn spec works in reality across the ecosystem. Actually that also is not true across the ecosystem for -8.

  • Current implementations - of authenticators, of clients and of RPs - that only support/request the old IDs will continue to work with the old identifiers.

Yes.

  • New implementations that support/request both IDs will work with both.

Yes, but they don't have to. There is no need, and this is extra work for Authenticators for no benefit. And new code means new potential bugs. And this is again guidance for the authenticators. May be there is some authenticator vendor who has not read all this conversation to only implement newer algorithms. And suddenly their release devices can't be fixed.

  • New RP implementations that request only the new IDs will not work with current authenticator implementations that only support the old IDs, so they are incentivized to also request the old IDs.

RPs will get it wrong.

Let's have one such example. Let's say that these newer Ecdsa algorithms gets supported on certain combination of browser/OS and RP didn't test all the platforms/Browser/OS combination. Just because they only tested major OS/Browser combination. I have seen this happen over the years. Also, we have already established that these new algorithms will not be supported on all authenticators/platforms. So, these RPs will have support costs for these unsupported combination situations down the road. Suddenly there is a situation that existing security keys for example does not work. Is RP staffed to add those? May be someone from RP says it is not the worth given their large population may not have security keys (I have seen this happen too). Then the user who has gone out of its way to buy such security key, will be left stranded.

You can add more guidance for the RPs. But even with current guidance, people get it wrong. Unless there was any issue with security/incompatibility/privacy, I don't think we should just add new definitions that can cause those incompatibilities.

Again, what is the need to introduce these new algorithms in WebAuthn? Agreed that they are not fully specified yet in COSE registry. But we have already made it clear in our spec about what those algorithms means.

  • Consequently, existing authenticator implementations do not need to update (even in new versions) and can continue supporting only the old IDs if they wish.

Provided that RP does the right thing. We shouldn't even open the possibility for RPs to get it wrong, IMO. There is no benefit. For example, if an RP wants ECDSA with ECC P-256 with SHA256, they use -7 today. There is no need to redefine it to something else.

  • New authenticator implementations that support only the new IDs will not work with current RP implementations that only request the old IDs, so they are incentivized to also support the old IDs.

Again, this is extra work for Authenticator for no benefit. All the cons of these proposals are because of various combinations of browsers/OS/Authenticators. Some are upgradable, some are not. And I don't think using these existing identifiers is even a problem.

  • Consequently, existing RP implementations do not need to update (even in new versions) and can continue requesting only the old IDs if they wish.

Yes. That is the ideal state. Newer RPs shouldn't be thinking different from existing implementation that just works. We don't know how

So I agree, we're not going to realistically eliminate the old IDs short of a complete ecosystem-wide migration to PQC/etc. But eliminating the old IDs was never a goal either, so I don't see how that is a problem?

Note also that the new IDs will be available for RPs to request and for authenticators to implement regardless of whether we make any change to WebAuthn. The COSEAlgorithmIdentifiers are registered, and WebAuthn L1 and L2 allow any COSEAlgorithmIdentifier to be used. WebAuthn L3 will too unless we explicitly forbid these specific values (which would in my opinion be worse). All this PR does is inform RPs of this new reality: that for maximum compatibility they should request both the old and new IDs (well ok, it does also carry the format restriction on from ES* to ESP*, but that is not what introduces the new alg IDs).

Overall, there is no benefit of adding these new algorithms for existing algorithms defined in WebAuthn spec.

@zacknewman
Copy link
Contributor

zacknewman commented May 20, 2025

@emlun, almost all of the points you made are true without this PR as well. Without this PR, RPs can still add support for these new IDs; so I don't see how there is benefit in mentioning them in the spec. Two, adding these IDs is more work even if they're only "recommendations" for user agents, authenticators, and RPs. That is not even debatable in WebAuthn Level 4 if they were to become required. So if we accept that the legacy IDs will always need to be supported and RPs are always allowed to support IDs in the registry even if they're not explicitly mentioned in the spec (e.g., the new ones mentioned here)—in fact the spec permits IDs outside of the registry—then what's to be gained other than a more complex spec that doesn't actually add anything useful?

Another way to view this is now with these new IDs there are two equivalent IDs, from the perspective of WebAuthn, so we arbitrarily pick one (i.e., the legacy ID) to recommend. Fortunately, this "choice" doesn't require any changes to the spec; but if desired, one could add a note about why this "choice" is made. WebAuthn shouldn't make the list of recommended IDs too long; otherwise let's just add the entire registry to the list of recommendations. WebAuthn already "arbitrarily" makes choices (e.g., using the uncompressed P-256 point form), so there is nothing "weird" about the list of recommended IDs.

If this were to go in, then you make a great point about getPublicKey. Currently user agents are required to return SPKI data from that function when the corresponding ID is EdDSA, ES256, or RS256. Presumably we add that user agents are required to support the new IDs as well? Fortunately the SPKI data itself is not affected by these new IDs since it only concerns itself with the public key data, but that doesn't change the fact that the user agent still needs to be updated to recognize the new ID.

emlun added 2 commits May 20, 2025 20:39
To reflect that the COSEAlgorithmIdentifier used in this test vector is in fact
`EdDSA (-8)`, not the recently registered `Ed25519 (-19)`.
@emlun
Copy link
Member Author

emlun commented May 20, 2025

@akshayku

[...] There is no need, and this is extra work for Authenticators for no benefit. And new code means new potential bugs. And this is again guidance for the authenticators. [...]

I was about to say there is no change in guidance for authenticators here, but on second thought I guess the changes to §6.5.1.1. Examples of credentialPublicKey Values Encoded in COSE_Key Format do qualify, as do the new/updated test vectors. Good point!

Again, what is the need to introduce these new algorithms in WebAuthn? [...]

Without it, authenticators that choose to implement support for ESP256 (-9) would be free to emit ESP256 COSE keys in compressed format since that is not forbidden for ESP256. Would that be a problem? RPs likely won't expect the compressed format and would have to update their code to support those authenticators that use the compressed format.

On the other hand I argued earlier that some incompatibility should be expected with new features, so maybe that's fine. Honestly I would prefer to drop the restriction against compressed format for ESP*, I just figured we would cause fewer problems (i.e., less work for RPs) continuing that restriction for ESP* than we would by having it for ES* but not for ESP*.

@zacknewman

Another way to view this is now with these new IDs there are two equivalent IDs, from the perspective of WebAuthn, so we arbitrarily pick one (i.e., the legacy ID) to recommend.

No, not either one - we should always recommend the legacy ID, the only question is whether we should also recommend the new one. I believe there is no harm in recommending the new ID and the old ID, and little or no harm in continuing to recommend only the old ID, but there certainly is harm in recommending the new ID instead of the old ID.

So okay, I guess "little or no harm in continuing to recommend only the old ID" may be a signal that we should do just that.

[...] about getPublicKey. Currently user agents are required to return SPKI data from that function when the corresponding ID is EdDSA, ES256, or RS256. Presumably we add that user agents are required to support the new IDs as well?

We're not adding that requirement in L3. getPublicKey() is still required to support EdDSA (-8), ES256 (-7) and RS256 (-257), but is not required to support Ed25519 (-19) or ESP256 (-9). Ed25519 (-19) and ESP256 (-9) should be "supported" in pubKeyCredParams just like they are today - in that the client doesn't throw an exception if you pass pubKeyCredParams: [{ alg: -9, type: "public-key" }]), but not necessarily in getPublicKey(). This is what's defined in the current L3 draft (without this PR) and I do not intend to change that in L3 (nor necessarily in L4+ if there are objections to it).


Okay, I've been convinced that we should at least reduce the scope of this change to keep the old IDs the "preferred" ones in examples and test vectors. I've updated the PR with that (I also changed the Ed25519 test vector to use the seed 'packed.EdDSA' instead of 'packed.Ed25519' since it is using the COSE identifier EdDSA (-8), in case we add an Ed25519 (-19) test vector in the future).

I could go either way on recommending that RPs request the new IDs (in addition to the respective old ones) in pubKeyCredParams. I've kept it in the PR for now. I think we should at the very least have some note saying if an RP requests one of the new IDs they really SHOULD also request the old one.

For now I've also kept the restriction against compressed form for ESP* public keys, but I'm happy to drop that too if we think it's a good idea for both compressed and uncompressed formats to coexist (but only with the new ESP* IDs, not with the old ES* IDs).

@emlun emlun changed the title Use fully-specified COSEAlgorithmIdentifiers in examples and recommendations Mention fully-specified COSEAlgorithmIdentifiers in examples and recommendations May 20, 2025
@emlun emlun requested a review from selfissued May 20, 2025 18:49
@zacknewman
Copy link
Contributor

zacknewman commented May 20, 2025

I could go either way on recommending that RPs request the new IDs (in addition to the respective old ones) in pubKeyCredParams. I've kept it in the PR for now. I think we should at the very least have some note saying if an RP requests one of the new IDs they really SHOULD also request the old one.

There is no need to tell RPs that request the new IDs that they SHOULD also request the old one since the old IDs are always recommended (i.e., regardless if an RP requests the new IDs, they SHOULD request the old IDs); as a result, I think the PR should be changed to remove the recommendation in pubKeyCredParams for the new IDs.

There is harm in adding the new IDs. It adds complexity to the spec that doesn't need to be there. There is a reason that only 3 IDs are recommended for pubKeyCredParams. Why is ES512 not in the recommended list of pubKeyCredParams? I claim the answer to that question is the same answer to "why is Ed25519 not in the recommended list of pubKeyCredParams?" We already have an ID, EdDSA, that represents Ed25519; and we don't want that list to be larger than necessary.

I will say that removing the restriction for ESP* IDs to allow them to be encoded as octet-key pairs (OKPs) does make them quantitatively different than their legacy counterparts; and further allowing them to be compressed aligns better with the concise nature of CBOR; however encoding points on the curve in anything other than the uncompressed form is highly unusual not only because the legacy version requires the uncompressed form but so many standards (e.g., RFC 5480) require support for the uncompressed form and neither require nor recommend support for the compressed form. This is further validated by your initial requirement that such IDs be encoded in the uncompressed form.

There is no such difference between EdDSA and Ed25519, however; as both seemingly require to be encoded as OKPs since I haven't seen any standard that defines an "uncompressed" encoding unlike curves like P-256. As a result, I'm still not convinced that adding them to the list of recommended pubKeyCredParams makes sense.

Last, I think it's worse to remove the test vectors and examples for the new IDs but keep the recommended pubKeyCredParams since having test vectors and examples make it less likely for implementations to be wrong.

Copy link
Contributor

@selfissued selfissued left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks ready to merge.

@emlun
Copy link
Member Author

emlun commented May 21, 2025

I will say that removing the restriction for ESP* IDs to allow them to be encoded as octet-key pairs (OKPs) [...]

COSE does not allow encoding ESP* keys with the OKP type. ECDSA public keys are required to use the EC2 key type; see RFC 9053 §7.1. Elliptic Curve Keys and RFC 9053 §2.1. ECDSA:

When using a COSE key for this algorithm , the following checks are made:

  • The "kty" field MUST be present, and it MUST be "EC2".
    [...]

Only Edwards curve keys (currently) are allowed (and indeed required) to use OKP, and yes, RFC 8032 defines a single canonical encoding for EdDSA keys.

Rather, it's the EC2 key type that has two variants: compressed or uncompressed y coordinate.

@emlun
Copy link
Member Author

emlun commented May 21, 2025

I've now also reverted adding the new algs to recommendations and examples, per @akshayku's argument that if RPs should continue using the old values anyway, we should not recommend using the new ones.

I've still kept the restriction against point compression for ESP*, for consistency with ES*.

@emlun emlun changed the title Mention fully-specified COSEAlgorithmIdentifiers in examples and recommendations Account for new fully-specified ECDSA and Ed448 COSEAlgorithmIdentifiers May 21, 2025
@zacknewman
Copy link
Contributor

zacknewman commented May 21, 2025

COSE does not allow encoding ESP* keys with the OKP type. ECDSA public keys are required to use the EC2 key type

Indeed. Thanks for the correction. I assumed the reason the OKP parameter for the public key was called x was for curves like P-256 since the compressed point is represented as the x-coordinate with the y-coordinate parity bit in contrast to curves like ed25519 whose points are encoded as the y-coordinate with the x-coordinate parity bit thus y would be the more appropriate parameter name. That's what I get for not re-reading RFC 9053.

@emlun emlun requested review from akshayku and selfissued May 21, 2025 16:53
@emlun emlun merged commit 3bcf9d5 into main May 22, 2025
4 checks passed
github-actions bot added a commit that referenced this pull request May 22, 2025
SHA: 3bcf9d5
Reason: push, by emlun

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update COSEAlgorithmIdentifier examples and recommendations to prefer fully-specified alg IDs
8 participants