This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 26411 - Caller can't force JWK to be distinguished as public or private key
Summary: Caller can't force JWK to be distinguished as public or private key
Status: RESOLVED WONTFIX
Alias: None
Product: Web Cryptography
Classification: Unclassified
Component: Web Cryptography API Document (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Ryan Sleevi
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-22 21:37 UTC by Ryan Sleevi
Modified: 2014-09-25 18:35 UTC (History)
4 users (show)

See Also:


Attachments

Description Ryan Sleevi 2014-07-22 21:37:02 UTC
As far as I can tell from http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-31#section-6.3 , there is no format restrictions/requirements on JWKs and the use of the "d" parameter.

That is, while an RSA JWK with the parameters (n, e, d) is a RSA private key, it contains all of the necessary details to also be an RSA public key.

However, at an API layer, the caller cannot indicate simply that they wish for a JWK to be imported as a public or private key. Instead, that's inferred, based on the presence of a "d" parameter (
https://dvcs.w3.org/hg/webcrypto-api/raw-file/ee10c81e1141/spec/Overview.html#rsassa-pkcs1-operations )

This prevents the following use case:
Using a single object/buffer, import a JWK as both a public and private key, thus using one message to represent a 'full' keypair (tuple).

For the importKey operation, the caller can easily mask out the "d" from the dictionary supplied to importKey, and thus 'force' WebCrypto to treat it as a public key. However, no such option exists for unwrapKey.

This problem exists somewhat for PKCS#8 as well (e.g. an RSAPrivateKey structure from RFC 3447 contains the necessary fields for an RSAPublicKey, see http://tools.ietf.org/html/rfc3447#appendix-C ).
Comment 1 Ryan Sleevi 2014-07-22 21:37:51 UTC
Note; I don't feel strongly about this issue, and am happy to close as WontFix (since the sender can send the public/private key separately, and that's guaranteed to work for all key types/algorithms), but it was worth noting at least how WebCrypto behaves for these.
Comment 2 Mark Watson 2014-07-22 21:51:13 UTC
Perhaps the import / unwrap should return a KeyPair in this case ?
Comment 3 Ryan Sleevi 2014-07-23 01:45:56 UTC
(In reply to Mark Watson from comment #2)
> Perhaps the import / unwrap should return a KeyPair in this case ?

I'd be a little concerned with consistency across algorithms, in the event private key did not contain the public representation.

While I haven't thought through the implications, and I doubt it would directly affect us, I note that a number of smart cards have 'compressed' format representations where they can omit storing the public key ("for performance!"), so from the native/smart-card land, I've developed a bit of an aversion to API-coupling public/private keys as a "sure thing".

But like I said, I don't really think it's a problem. An alternative solution would be "two" formats, since "SPKI" and "PKCS8" are functionally "DER: Public Key" and "DER: Private Key", so you could argue (a bit perversely) that we should have "JWK: Public Key" and "JWK: Private Key" formats.

And this isn't beginning to touch the world of ECDH, or how things like "raw" would/should behave.
Comment 4 Richard Barnes 2014-08-05 16:46:33 UTC
Another way you could go about this is to add a way to get the public key that corresponds to a given private key.  This is clearly possible for EC and DH keys, and should pretty much always be possible for RSA keys.  That way the API could default to private key import if the private parameters are present, then you could translate over to the public if you need it.  As a bonus, this seems like something that could be useful more generally.

partial interface CryptoKey {
  readonly attribute CryptoKey correspondingPublicKey;
  // or
  CryptoKey correspondingPublicKey();
}

... then return null or throw if there's not a public key available (e.g., if the underlying key is a symmetric key).
Comment 5 Ryan Sleevi 2014-08-05 19:17:15 UTC
Note that I don't have any real or imagined use case for this. It was just worth documenting as a limitation. I don't hear anyone screaming for support, either.

(In reply to Richard Barnes from comment #4)
> Another way you could go about this is to add a way to get the public key
> that corresponds to a given private key.  This is clearly possible for EC
> and DH keys, and should pretty much always be possible for RSA keys.  That
> way the API could default to private key import if the private parameters
> are present, then you could translate over to the public if you need it.  As
> a bonus, this seems like something that could be useful more generally.

I intentionally avoided this during early drafts, because in many cryptographic libraries and implementation, this isn't possible/easy/reliable. This is, admittedly, primarily a concern induced by how hardware tokens behave, but one that has been reflected into the system APIs.
Comment 6 Richard Barnes 2014-08-05 19:38:06 UTC
(In reply to Ryan Sleevi from comment #5)
> Note that I don't have any real or imagined use case for this. It was just
> worth documenting as a limitation. I don't hear anyone screaming for
> support, either.

Sure.  I would be OK letting this drop.

 
> (In reply to Richard Barnes from comment #4)
> > Another way you could go about this is to add a way to get the public key
> > that corresponds to a given private key.  This is clearly possible for EC
> > and DH keys, and should pretty much always be possible for RSA keys.  That
> > way the API could default to private key import if the private parameters
> > are present, then you could translate over to the public if you need it.  As
> > a bonus, this seems like something that could be useful more generally.
> 
> I intentionally avoided this during early drafts, because in many
> cryptographic libraries and implementation, this isn't
> possible/easy/reliable. This is, admittedly, primarily a concern induced by
> how hardware tokens behave, but one that has been reflected into the system
> APIs.

It seems like this isn't necessarily a system API issue.  An implementation of CryptoKey could simply do two imports (public and private) and store both, even if the platform doesn't support private->public conversion.  I admit that it does impose some overhead.  As above, I'm OK letting this drop, but the private->public conversion does seem kind of handy.
Comment 7 Mark Watson 2014-09-22 18:01:56 UTC
The discussion here points towards 'won't fix'. Any objections ?