Re: Use case classification, and associated security models

On 6/12/2012 3:58 PM, Ryan Sleevi wrote:
>
>
> On Tue, Jun 12, 2012 at 3:30 PM, Mitch Zollinger 
> <mzollinger@netflix.com <mailto:mzollinger@netflix.com>> wrote:
>
>     On 6/12/2012 2:29 PM, Ryan Sleevi wrote:
>>
>>
>>     On Tue, Jun 12, 2012 at 1:31 PM, Mitch Zollinger
>>     <mzollinger@netflix.com <mailto:mzollinger@netflix.com>> wrote:
>>
>>         On 6/12/2012 12:53 PM, Ryan Sleevi wrote:
>>>
>>>
>>>         On Tue, Jun 12, 2012 at 12:38 PM, Mitch Zollinger
>>>         <mzollinger@netflix.com <mailto:mzollinger@netflix.com>> wrote:
>>>
>>>             On 6/12/2012 1:07 AM, Vijay Bharadwaj wrote:
>>>>             <snip>
>>>>
>>>>             In all the above cases, once a key is obtained, all the
>>>>             actual crypto operations are pretty much the same. So
>>>>             is we define all operations in the API which require a
>>>>             key such that they take a key object as a parameter,
>>>>             then the only difference between the above scenarios
>>>>             (from an API perspective) is the operations used to
>>>>             instantiate that key object. The above 3 scenarios
>>>>             would then correspond to 3 different instantiation
>>>>             methods for key objects:
>>>>
>>>>             1.GenerateKey – create a new key for use with a
>>>>             specific algorithm. Choice of crypto provider left up
>>>>             to the platform.
>>>>
>>>>             2.ImportKey – take a key blob obtained from key
>>>>             agreement and create a key object from it. Choice of
>>>>             crypto provider left up to the platform.
>>>>
>>>>             3.OpenKey – Locate a key on the host system that
>>>>             matches a set of criteria. Choice of crypto provider to
>>>>             be made by platform depending on the location of the key.
>>>>
>>>>             There is also a fourth primitive which is often used
>>>>             with scenario 3 – credential enrollment. This would be
>>>>             the operation where the user employs the trusted key to
>>>>             obtain a credential (e.g. enrolling for a smart card
>>>>             certificate by signing a request using one’s existing
>>>>             smart card key).
>>>>
>>>>             Does that seem reasonable? Any other families of use
>>>>             cases that I’m overlooking?
>>>>
>>>
>>>             Good write up.
>>>
>>>             I would like to better understand what you (and the
>>>             group) think about "crypto providers". When I think
>>>             about crypto providers, I think of the JCE (Java
>>>             Cryptography Extensions) Crypto Providers & OpenSSL
>>>             "engines". In that context, it would seem to me that the
>>>             app has varying behavior with regard to crypto provider
>>>             selection that may be orthogonal to the type of the key.
>>>             One example:
>>>
>>>             * If my app detects that a smart card is plugged in & I
>>>             can use keys on the smart card for service
>>>             authentication, I will not ask the user a security
>>>             question when they connect to my webapp. However, if I'm
>>>             using another crypto provider (likely the default
>>>             provided by the browser) -- with the same keys that
>>>             would have been stored in the smart card if the user had
>>>             it plugged in -- then I will ask my security question.
>>>
>>>             Mitch
>>>
>>>
>>>         I think that any app that would do what you propose, without
>>>         any other additional proof, would be making
>>>         a naive assumption that doesn't really improve the security.
>>>         I certainly do not want to expose any such concept to the
>>>         web API for exactly that reason.
>>>
>>>         In your example, you're relying on the user agent to
>>>         honestly answer "smart card" or "not smart card" for where
>>>         the key is stored, and then making a server side security
>>>         decision based on that.
>>
>>         I should have been more explicit. I'll echo much of what you
>>         say below (I agree with you):
>>
>>         When I say "same key" I'm referring to a key with the same
>>         *key name* in both contexts, not actually the same keying
>>         material or same UUID (I'm taking the liberty of assuming the
>>         UUID exists for now.)
>>
>>         The point is that the running web app / web service is making
>>         a decision on further authentication steps based on the
>>         provenance of the key: was it distributed out-of-bound and
>>         considered pre-shared or was it something I made up at webapp
>>         runtime?
>>
>>
>>>         Such a decision seems a lot like sticking form validation
>>>         code in the client to prevent against SQL injection.
>>>         Browsers can be mislead or manipulated, so I don't think it
>>>         can be reasonably assumed to give an answer that is reliably
>>>         accurate.
>>
>>         No reliance on trustworthiness of client side JS code assumed
>>         here.
>>
>>
>>>
>>>         Using Vijay's ontology, if you want to make the distinction
>>>         between secure element or not, you, as a service provider,
>>>         would do so based upon whether or not you (as a service
>>>         provider) were responsible for the provisioning ceremony of
>>>         those keys. If you controlled the ceremony, you know the
>>>         provenance of those keys, and you know how and where they're
>>>         stored.
>>
>>         Absolutely agree.
>>
>>
>>>
>>>         Whether this means mailing out a smart card, using some
>>>         other application/protocol/platform. Examples might be
>>>         GlobalPlatform, with it's proof of possessions, some work
>>>         product of the IETF's KeyProv WG, something like Anders
>>>         Rundgren's Keygen2, etc. However, the size and scope of
>>>         work, and the many competing interests involved, seem very
>>>         much out of scope for this WG (although admittedly very
>>>         interesting and perhaps parallel work to solve)
>>>
>>>         To modify your scenario into something that I think would
>>>         provide some reasonable assurances:
>>>         * If your app detects that the user has a (pre-provisioned
>>>         Key ID X), then you can allow that user to authenticate
>>>         using Key X.
>>>         * If your app does not detect Key X, but detects a
>>>         (previously generated via <keygen> or the ephemeral API
>>>         Vijay proposed), then it uses Key Y, plus some form of
>>>         challenge/security question.
>>>         * If your app detects neither Key X nor Key Y, it offers the
>>>         user the chance to (online enroll a Key Y, contact you to
>>>         obtain a smart card with Key X)
>>
>>         Yep. No disagreement from me with this approach. I would
>>         rewrite this as:
>>         * My app wants to use "AuthKey" to authenticate the client,
>>         wherever "AuthKey" may be.
>>         * The app attempts to use "HSMProvider" as the crypto
>>         provider; if that provider does not work or is not available,
>>         it falls back to "DefaultProvider". (For the moment, I'm
>>         ignoring the bootstrap of "AuthKey" into each of these
>>         providers.)
>>         * The app authenticates using "AuthKey", which has an
>>         associated UUID which allows me to map the key to one of (a)
>>         a key that I provisioned into an HSM (and accessible via
>>         "HSMProvider") or (b) a key entrusted to the "Default" provider.
>>         * The server side decides, based on Provider/UUID whether to
>>         initiate further authentication steps.
>>
>>         Mitch
>>
>>
>>     I'm not sure the providers are necessary here, which is part of
>>     why I'm somewhat opposed to them.
>>
>>     Using the KeyQueryList sort of example from the other thread, I
>>     would think you'd simply set a KQL for "some criteria"
>>     (admittedly, hand-wavey), and you would get back (assuming the
>>     user approved/pre-approved) two keys.
>>
>>     At that point, you have two keys you're interested in. The
>>     question is which (or perhaps both) you want to use for the
>>     signing operation. Your web app may make a query to the server
>>     and say "I have these two keys, which would you like to use" - at
>>     which point, the server might say "Use this one, I know because I
>>     presided over the ceremony".
>>
>>     Your web app may have already sent that list to the client, and
>>     the client JS then knows that key X is preferable over key Y, and
>>     upon seeing that it has both Key X and Key Y, attempts the
>>     authentication protocol first with Key X.
>>
>>     You may even show a UI (using your web apps branding) to allow
>>     the user to select which key they wish to use, similar to sites
>>     that offer multi-login or oauth/saml style workflows.
>>
>>     At no point does the application need to be exposed to the crypto
>>     provider or how the key is backed - it's simply a key handle that
>>     it can use.
>>
>>     My guess (perhaps completely unfounded, based on our current
>>     participants) is that most applications using this API will not
>>     care about "DefaultProvider" or "HSMProvider", and certainly, I
>>     think it introduces a whole host of new, cross-browser
>>     standardization issues. For example, consider if we have two
>>     implementations, one based on PKCS#11 (eg: Mozilla Firefox,
>>     Chrome for Linux) and one based on CryptoAPI/CNG (eg: Internet
>>     Exporer, Chrome for Windows, Safari for Windows). Both OS-level
>>     APIs may be talking to the same logical smart card/key
>>     store/secure element, but because of the very different nature of
>>     the APIs, have very different naming schemes to identify them.
>>
>>     Using the above example, is there a scenario/workflow where "Try
>>     to find Key X, then try to find Key Y", in application logic, is
>>     more desirable than "Query for Key X or Key Y", and then in
>>     application logic making a decision based upon the response you got?
>
>     We can work with either mechanism. What I've described (the two
>     keys have the same "name" and the provenance is implied by the
>     UUID) fits better conceptually with what we're doing today, but I
>     could just as easily query for the two keys and use whatever one I
>     got back without worrying explicitly about provenance.
>
>     I guess I'm not seeing how KeyQueryList would be used. Given that
>     you and Wan-Teh are advocating for something along these lines,
>     it's clear I'm missing something. (I know very little about smart
>     card usage, so this is not surprising.) Could you give an example?
>     In other words, could you fill in the [Some, Criteria, Here]
>     portion of your pseudo code example?
>
>>     var kql = window.crypto.queryKey([Some, Criteria, Here]);
>
>     Mitch
>
>
> Wan-Teh hasn't quite chimed in here on KQL, so I don't presume to 
> speak for him :-)
>
> The [Some, Criteria, Here] is, in part, dependent upon the ontology of 
> key types we're talking about. Whether Vijay's notation or my original 
> suggestion of "ephemeral, persistent, and high-value", it does seem 
> like we agree on some distinction between "shared" (between origins / 
> between other services) and "origin bound" (as the charter and 
> original discussions focused on). The parameters to queryKey are going 
> to necessary reflect whatever dimensions we determine are both 
> relevant for key management and within the scope of the charter.
>
> There needs to be symmetry between the create/derive functions and the 
> query functions, although understandably there will be some slight 
> differences since you can't create pre-provisioned keys :)
>
> // Find all RSA keys that are usable for OAEP. Additionally, the 
> keying material must be available for
> // the script to use (perhaps it implements some custom scheme that 
> builds atop OAEP) and it must not
> // be a key that is cleared when the user clears their browsing data 
> (eg: it must be 'long-lived/persistent',
> // which is conceptually similar but slightly different than Vijay's 
> 'pre-provisioned' category)
> var kql = window.crypto.queryKey(
>   {
>     'algorithm': 'RSA',
>     'mode': 'OAEP',
>     'extractable': true,
>     'temporary': false,
>   });
>
> // Retrieve all AES keys available for use with CBC mode. They may be 
> temporary keys or
> // persistent keys, it may be keys that were randomly generated and it 
> may include keys that
> // were derived from some other algorithm (eg: an ECDHE exchange). No 
> particular expression
> // about how it is stored is made.
> var kql = window.crypto.queryKey(
>   {
>     'algorithm': 'AES',
>     'mode': 'CBC',
>   });
>
> // Retrieve all keys (See [1]) that are backed by a certificate, whose 
> issuer is one of IssuerName 1 or
> // IssuerName 2. This may return both RSA and ECC keys, since no 
> 'algorithm' has been specified. The
> // key must be usable for signing (which may be ascertained as part of 
> the key store or may need to
> // be inferred from the KU/EKU of the associated certificate(s))
> var kql = window.crypto.queryKey(
>   {
>     'operation': 'sign',
>     'certificate': {
>       'issuer': [
>         [ ArrayBuffer of DER IssuerName 1],
>         [ ArrayBuffer of DER IssuerName 2],
>       ],
>     },
>   });
>
> [1] This opens the general API discussion about whether or 
> not asymmetric algorithms return one key handle (for a public/private 
> key /pair/) or two key handles (one for public, one for private). For 
> example, by constraining the operation to 'sign', we imply a private 
> key (since 'verify' would be public key), 'encrypt' implies public and 
> 'decrypt' implies private. However, it may be better to explicitly 
> specify rather than implicitly specify.
>
>
> If we adopt some form of UUID notation (which I still need to mull 
> over the privacy risks), one might further expand to
>
> var kql = window.crypto.queryKey(
>   {
>     'id': [ 'UUID_1', 'UUID_2' ],
>   })
>
> or with an origin-specified naming scheme:
>
> var kql = window.crypto.queryKey(
>   {
>     'name': 'NetFlixAuthenticationKey',
>   });
>

Thanks for the examples. This makes sense to me now. It is a much more 
comprehensive querying mechanism relative to the simple "named" 
credentials approach. Either approach will work for us.

Mitch

Received on Wednesday, 13 June 2012 02:55:57 UTC