- From: Ryan Sleevi <sleevi@google.com>
- Date: Tue, 11 Mar 2014 18:00:13 -0700
- To: Mark Watson <watsonm@netflix.com>
- Cc: public-webcrypto@w3.org
- Message-ID: <CACvaWvZJ93uWhj9cz8Rf-gvqHVMi48c=tSmkTFQtazhDiB+fWg@mail.gmail.com>
On Mar 11, 2014 5:44 PM, "Mark Watson" <watsonm@netflix.com> wrote: > > Hi Ryan, > > This looks good with the following comments: > > (1) Why not add this capability, whilst keeping the existing JWK import / export ? For example add a new format "jwk-obj". This would keep things simple for the other use-case where the JWK is just being written to / read from a wire protocol. Supporting both is hardly arduous since UAs must support the serialization / de-serialization for wrap / unwrap anyway. > We should prioritize the common case. Dealing with ArrayBuffers for JSON or JS Objects is not the common case for any other Web API. If we support parallel formats, it should be because we believe the ArrayBuffer case will be as significant a use case as with Object. In either event, if we do support both, I believe the ArrayBuffer case should be separately named (eg: JWKS) - precisely because JWK will naturally yield or be manipulated as Objects, not octets, within JS. You keep saying "written to or read from a wire protocol", so I'd simply ask that you back that assertion up with script demonstrating this use case. The most likely candidates - XHR and WebSockets - are naturally inclined towards JSON and DOMString-ified JSON. Equally true for structured inter-origin postMessage (which may not be suitable as a Key object if the source is replaying a message from the server to the peer). These are all cases served by a natural object - especially when it reduces repeated conversions / copies. Equally, if we believe that really, the use case is only for importing an ArrayBuffer, we could let the "jwk" importKey handle both cases transparently, while always yielding an object for export key. TL:DR; What is a precise use case or demonstrable snippet where ArrayBuffer would be more preferable or natural compared to an Object? > (2) WebIDL appears to be a little ambiguous with respect to unions of Dictionaries. Section 14.2.25 says "If types includes a dictionary type, then return the result of converting V to that dictionary type. > ", which pointedly neglects to say which dictionary type in types, if there is more than one. > Sure. We could just as well deal with it as we deal with algorithm - object and coercion. I agree this has to be solved meaningfully before adding to the spec. > (3) We need a > JwkKeyDictionary subclass for symmetric keys: > > JwkSecretKeyDictionary : JwkKeyDictionary { > DOMString k; > }; > > (4) usages in JwkKeyDictionary should be "key_ops" > > (5) Do we want to include the "use" member ? I thought we checked that for consistency ? > All oversights of mine, as a result of basing on JWA without reading all of our additions/registrations. Answer is yes, yes, and yes. > ...Mark > > > On Tue, Mar 11, 2014 at 5:22 PM, Ryan Sleevi <sleevi@google.com> wrote: >> >> The motivation: >> >> * Provide a means of easy interchange with Web Sockets (eg: by allowing Text Frame, rather than imposing Binary Frame, as done by send(ArrayBuffer) ) >> * Provide a means of easy interchange of JWK with postMessage (eg: by not requiring a Key object itself be posted) >> * Provide a means of easy integration with larger JSON-backed messages >> >> That is, presume a structure >> { >> 'larger_message': 'something', >> 'jwk': [{ >> 'kid': 'foo', >> 'alg': 'RSA', >> 'kty': 'RSA1_5', >> 'n': '....', >> 'e': '....' >> }] >> } >> >> Under the current API, one has two options - depending on UA support for http://encoding.spec.whatwg.org/#api >> >> With Encoding support: >> >> // Makes 3 additional copies of message.jwk >> // 1 for the .stringify >> // 1 for the TextEncoder >> // 1 for the importKey (cloning the ArrayBuffer) >> // By definition, this copies *all* fields of message.jwk, including those not used by importKey (eg: 'kid') >> >> message = JSON.parse(message); >> jwkBuf = (new TextEncoder("utf-8")).encode(JSON.stringify(message.jwk)); >> window.crypto.subtle.importKey("jwk", jwkBuf, { name: "RSAES-PKCS1-v1_5" }, [ "encrypt", "decrypt"] ); >> >> Without Encoding support: >> It's necessary to do something like strToUTF8Arr ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding) >> >> Under the proposed API, one simply does >> >> // Makes 1 additional copy of message.jwk >> // 1 for the importKey (cloning message.jwk) >> // By definition, this *does not* copy all fields of message.jwk - only those fields used for the import (eg: 'kid' is NOT copied) >> window.crypto.subtle.importKey("jwk", message.jwk, { name: "RSAES-PKCS1-v1_5" }, [ "encrypt", "decrypt" ]); >> >> >> Types used: >> >> dictionary JwkKeyDictionary { >> DOMString kty; >> DOMString alg; >> boolean ext; >> DOMString[] usages; >> }; >> >> dictionary JwkEcKeyDictionary : JwkKeyDictionary { >> DOMString crv; >> DOMString x; >> DOMString y; >> DOMString d; >> }; >> >> dictionary JwkRsaOtherPrimeDictionary { >> DOMString r; >> DOMString d; >> DOMString t; >> }; >> >> dictionary JwkRsaKeyDictionary : JwkKeyDictionary { >> DOMString n; >> DOMString e; >> DOMString d; >> DOMString p; >> DOMString dp; >> DOMString dq; >> DOMString qi; >> JwkRsaOtherPrimeDictionary[] oth; >> }; >> >> >> >> Changes to signatures: >> Old: >> Promise<any> importKey(KeyFormat format, CryptoOperationData keyData, AlgorithmIdentifier? algorithm, boolean extractable, KeyUsage[] keyUsages); >> Promise<any> exportKey(KeyFormat format, Key key); >> >> New: >> Promise<any> importKey(KeyFormat format, (CryptoOperationData or JwkRsaKeyDictionary or JwkEcKeyDictionary), AlgorithmIdentifier algorithm, boolean extractable, KeyUsage[] keyUsages); >> Promise<any> exportKey(KeyFormat format, Key key); >> >> >> Changes to algorithms: >> Wrap Key ( 14.3.1 / https://dvcs.w3.org/hg/webcrypto-api/raw-file/3f7df730b2c7/spec/Overview.html#SubtleCrypto-method-wrapKey) >> >> 12. >> * If format is "spki": >> - Let bytes be the result of performing the export key operation specified the algorithm attribute of key using key and format. >> * If format is "pkcs8" >> - Let bytes be the result of performing the export key operation specified the algorithm attribute of key using key and format. >> * If format is "jwk" >> - Let object be the result of performing the export key operation specified by the algorithm attribute of key using key and format. >> - Let stringifiedJwk be the result of invoking the JSON.stringify method specified in Section 15.12.3 of [ECMA-252], with /object/ as /value/. >> - Let bytes be the UTF-8 encoding of stringifiedJwk >> >> >> From the algorithm-specific import key sections eg: using https://dvcs.w3.org/hg/webcrypto-api/raw-file/3f7df730b2c7/spec/Overview.html#rsassa-pkcs1-operationsas an example >> >> 4. If format is "jwk" >> 1. If /keyData/ is not an instance of a JwkRsaKeyDictionary, return an error ... >> 2. Let /jwk/ be /keyData/ >> >> From the algorithm-specific export key sections - eg: using again RSASSA-PKCS1 >> >> 4. If format is "jwk" >> * Let /jwk/ be a new ECMAScript object created as if by the expression ({}) >> * _Set the property "n" of /jwk/_ to the _base64url-encoded_ modulus of the RSA public key represented by /key/, as specified by Section 6.3.1 of [JWA] >> * _Set the property "e" of /jwk/_ to the _base64url-encoded_ big integer exponent representation of the RSA public key represented by /key/, as specified by Section 6.3.1 of [JWA] >> ... >> * Let /result/ be /jwk/ >> >> Terminology: >> When this specification says Set the property /name/ of /object/ to /value/, call the [[DefineOwnProperty]] internal method of /object/ with property name /name/, the Property Descriptor { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true, [[Value]]: /value/ }, and the Boolean flag false. >> >> >> > >
Received on Wednesday, 12 March 2014 01:00:42 UTC