Subject: Determining strength of encryption provided by a GSS-API mechanism

From: Alexey Melnikov <[email-masked]>
Date: Tue, 11 Aug 2009 13:10:47 +0100

In continuation of the discussion in Stockholm about what can be done in 
the WG that is of interest to implementors, I have one minor request.

I am working on a Cyrus SASL plugin that either uses GSS-API or SSPI. 
SASL uses a thing called Strength Security Factor (SSF) to determine if 
a particular authentication mechanism is allowed by client or server 
security policy. SSF roughly correspond to the key size for symmetric 
ciphers, with SSF==0 being no privacy and no integrity, and SSF==1 being 
integrity only. (I am not going to defend the concept of SSF, but I 
think it is relatively easy to understand by sysadmins and it seems to 
work.) Each Cyrus SASL plugin needs to advertise its minimal and maximal 
supported SSF, so the maximal SSF is going to be the strength of the 
strongest supported symmetric cipher.

What I am missing is some API for retrieving SSF provided by a GSS-API 
mechanism's gss_wrap() with privacy, as well as for retrieving the best 
SSF that can be provided by the mechanism. Is such API already 
available, and if the answer is no, are people interested in working on 
defining it?

Thanks,
Alexey

---

From: Love Hörnquist Åstrand <[email-masked]>
Date: Tue, 11 Aug 2009 23:42:53 +0200

11 aug 2009 kl. 14:10 skrev Alexey Melnikov:

>  Is such API already available

no

> and if the answer is no, are people interested in working on  
> defining it?

sure, I think the definition of SSF is broken, and its not simple to  
understand, racing to yet another higher number seems bad.

Love

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 12 Aug 2009 13:16:33 -0500

> > Is such API already available

Though we've discussed designs for APIs that allow applications to
request / determine which strength profiles to use / are in use.

> understand, racing to yet another higher number seems bad.

Indeed.  SSF is bad, bad, bad.

It's not possible to permanently assign a "strength" number to a
mechanism or "enctype".  Strength is in the eye of the beholder and may
vary with time.  And users shouldn't, and likely don't, care about
numeric strength representations -- they should, and probably do, care
about strength representations in their language, such as "strong",
names of standards (e.g., "fips140-1"), and so on.

IMO only relative strength should matter, and rather than use numbers we
should use names of policies, policies that can be created and
maintained locally or, in the case of policies that correspond to
standards, delivered by vendors and updated as those standards are
updated.

No, that's not helpful to you: even if we had such GSS APIs you'd still
have to introduce equivalent SASL APIs and you'd still have to do
something about SSF for backwards compatibility.

Nico
--

---

From: Alexey Melnikov <[email-masked]>
Date: Wed, 12 Aug 2009 21:08:53 +0100

>request / determine which strength profiles to use / are in use.
Can you provide a pointer?

>IMO only relative strength should matter,
>
This is how SSF is used, for the most part. But you are right, there is 
no way to reclassify a cipher as weak using SSF.

>and rather than use numbers we
Well, if the WG can provide a way to control and determine which ciphers 
are supported, this would be great.

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 12 Aug 2009 16:25:02 -0500

> Can you provide a pointer?

Searching my sent box for mails with "qop" in the subject I see this:

    Date: Fri, 22 Sep 2006 10:33:34 -0500
    From: Nicolas Williams <[email-masked]>
    To: Alexey Melnikov <[email-masked]>
    Cc: Hai Zaar <[email-masked]>, [email-masked]
    Subject: GSS-API QoPs and SASL SSF (Re: SASL always returns ssf=56 for GSSAPI)

> no way to reclassify a cipher as weak using SSF.

Apps hardcode SSF values at build time, as do mechanisms.  That means
they can't be changed without rebuilding and redeploying code.  That's
bad.

There's other things that are bad:

 - numbers for this just suck; policy names are much better
 - strength may be context-specific, as in the case of the Kerberos V
   GSS-API mechanism (where the enctype used is completely independent
   of the SASL mechanism name / GSS mech OID)

> are supported, this would be great.

One could do this with an extension for credentials acquisition, another
for security context inquiry, and a way to do policy<->QoP mapping
(though one would never need it -- just for completeness).  Something
like:

/*
 * Set the policy that may be used to establish security contexts, and
 * the policy that will be used as the default QoP (GSS_C_QOP_DEFAULT)
 * for per-message token functions (gss_wrap() and friends).
 *
 * (We could also just add a variant of gss_add/acquire_cred() instead
 * of modifying an existing cred handle.)
 */
OM_uint32
gss_set_cred_policy(
	OM_uint32	*minor_status,
	gss_cred_id_t	input_cred,
	gss_OID		mech,
	gss_cred_id_t	*output_cred,
	gss_buffer_t	context_establishement_policy,
	gss_buffer_t	per_msg_token_policy
);

OM_uint32
gss_add_cred_policy(
	/* same args as gss_add_cred() */
	...
	/* plus: */
	gss_buffer_t    context_establishement_policy,
	gss_buffer_t    per_msg_token_policy
);
...

/*
 * Find out the name of a policy that was used to establish a security
 * context, and the name of the policy that set the default QoP for that
 * security context.
 */
OM_uint32
gss_inquire_sec_context_policy(
	OM_uint32	*minor_status,
	gss_ctx_id_t	ctx,
	gss_buffer_t	context_establishement_policy,
	gss_buffer_t	per_msg_token_policy
);

OM_uint32
gss_qop_to_policy(
	OM_uint32	*minor_status,
	gss_buffer_t	per_msg_token_policy,
	gss_qop_t	*qop
);

OM_uint32
gss_policy_to_qop(
	OM_uint32	*minor_status,
	gss_qop_t	qop,
	gss_buffer_t	per_msg_token_policy
);

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 12 Aug 2009 16:55:04 -0500

> 	gss_buffer_t	per_msg_token_policy

These buffers would have policy names, in the caller's locale's codeset,
or maybe just all US-ASCII.  We'd also need a function to get localized
policy names (and descriptions).  And we'd need a namespace for
standards-based policy names vs. local policy names.  Plus a policy
comparison function.

OM_uint32
gss_display_policy(
	OM_uint32	*minor_status,
	gss_buffer_t	policy,
	gss_buffer_t	localized_name,
	gss_buffer_t	localized_desc,
	int		*is_context_establishement_policy,
	int		*is_per_msg_token_policy
);

A function for listing known policies would also be nice.  The contents
of policies would be purely local; no interchange format is needed.

/*
 * 'result' is set to 1 if policy1 is a superset of policy2, 0 if the
 * two policies are equivalent, and -1 if they are disjoint or if
 * policy2 is a superset of policy1.
 *
 * If mech is GSS_NO_OID then the comparison is across all available
 * mechanisms.  (Internally the framework would call the
 * compare_policies method for each available mechanism, and set result
 * to 1 or 0 only if all the comparisons output the same non-negative
 * value, else -1.)
 */
OM_uint32
gss_compare_policies(
	OM_uint32	*minor_status,
	gss_OID		mech, /* may be GSS_NO_OID */
	gss_buffer_t	policy1,
	gss_buffer_t	policy2,
	int		*result
);

---

From: Alexey Melnikov <[email-masked]>
Date: Wed, 12 Aug 2009 23:26:28 +0100

>    Subject: GSS-API QoPs and SASL SSF (Re: SASL always returns ssf=56 for GSSAPI)
:-).

>Apps hardcode SSF values at build time,
>
Actually apps don't. My server certainly doesn't. It has 2 file 
configuration options: min_ssf and max_ssf for controlling use of 
security layers.

>as do mechanisms.
Mechanisms do, because they have no way of learning from GSS-API. So 
either mechanisms have to hardcode the highest known value, or they need 
to lie that they support certain SSF.

>That means
Well, it means you need to have entirely different API and, more 
importantly, UI for managing such policies. Good UIs like this are 
difficult.

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 12 Aug 2009 17:42:17 -0500

> >Searching my sent box for mails with "qop" in the subject I see this:

:)

> configuration options: min_ssf and max_ssf for controlling use of 

Ah, I stand corrected.

> to lie that they support certain SSF.

Right.

> importantly, UI for managing such policies. Good UIs like this are 

I have given the subject much thought, though intermittently, over the
past few years.  I believe the API that I've sketched for you is a very
good start, and that it makes it possible to have very simple UIs for
users and server configuration.

The hard part is about how to express policies.  E.g., a simple "must
use AES" is not enough, and policies are almost unavoidably going to
have mechanism-specific contents.  But fortunately, because policy
contents is a local problem, policy expression is not our problem here :)

(Policy interchange formats are not really a problem that we need to
solve either.  Standard policies could be expressed in English, with the
task of expressing them in machine-readable form being left to
implementors.)

Nico
--