Straw-man for security parameter placement

Brent Putman putmanb at georgetown.edu
Wed Mar 12 17:33:55 EDT 2014


Sorry for just getting to this, I've been heads down the last 2 days on
GU work, and also my Shib Eclipse workspace in the office is hosed at
the moment...


On 3/9/14 6:35 PM, Cantor, Scott wrote:
> Mainly to Brent...
>
> I'm wondering if we need to split up the EncryptionParameters into Data
> and Key types to represent the difference between whether and how to
> encrypt the data and who to encrypt it for?

I'd note at the outset re: the EncryptionParameters that it isn't
assumed that all the properties on a given instance are populated.  In
particular, the 3 slots related to data encryption will often be null,
since the Encrypter can and usually does just auto-generate an ephemeral
data encryption Credential internally.  The dataEncryptionAlgorithmURI
might and probably will be populated based on a resolved preference from
configuration and/or metadata (although it doesn't have to be, the
Encrypter inputs effectively have an internal default of AES-128). The
dataKeyInfoGenerator isn't used in at least most SAML cases - the
EncryptedData gets a KeyInfo with the EncryptedKey, if you're using
INLINE key placement, and that doesn't come from a generator since it's
an internal detail of the Encrypter.

So in a way there's not much reason to split them in practice....  But
if you really wanted to have 2 different instances, you could
theoretically just have 2 instances of EncryptionParameters: one with
just the data slots populated and one with just the keyTransport slots
populated.  But really, thinking of them as being separate (whether
different classes or not) I think isn't conceptually correct, since the
type of key encryption that is chosen depends (or *can* depend), in
part, on the type of key you are encrypting.  And so it seems to me they
have to be resolved together, hence just a single EncryptionParameters
class.

Speaking of multiple RP's and key multicasting, there is an issue there
in general (not just with our code) of what data encryption algorithm to
use.  More on multiple RP's and key multicast later.

>
> I can't pull a single parameter set from a RelyingPartyContext as a signal
> whether to encrypt because that doesn't tell me which objects need to be
> encrypted. But if we split these, I could create separate subcontexts for
> the different types of objects that might need encryption and hang those
> off the profile context, but put the KeyEncryptionParameters below the
> RelyingPartyContext.

I guess I don't see those 2 things as necessarily related.  In practice,
based on the resolved config and metadata prefs of the RP, all 3 SAML
types would have the same data encryption algorithm URI anyway. I don't
know of any way to signal differences there.

The only reason to split them to multiple instances that I can see would
be if we wanted to have the resolver actually auto-generate the
ephemeral data encryption Credential itself, rather than let the
Encrypter do it (the assumption being that you don't want to reuse the
same data encryption key for multiple encryption ops). 

Aside from the fact that we don't need to (since the Encrypter does it),
that doesn't really fit at the moment with my (evolving) notion of how
the -Resolvers work and what they do.  They are really about resolving
and winnowing down preference lists coming from 1 or more -Configuration
instances (which have order-of-precedence) + metadata.

But if we did want to do that, I'd argue for keeping things simple and
just having a single EncryptionParameters class.  The multiple instances
that would be resolved for the 3 cases (with different
dataEncryptionCredentials), would just happen to have the same data for
the keyTransport* slots (in particular the
keyTransportEncryptionCredential, since for a given RP you're typically
going to always resolve the same one anyway, at least with SAML and keys
coming from metadata).

> Otherwise we'd have to combine the idea of presence/absence as a signal
> with something more fine grained to tell what to do.

Re: signalling whether to encrypt for the 3 distinct SAML 2 types
(Assertion, Attribute, NameID): In the first email in the thread you
were proposing not having distinct security context param "slots" for
these to do the signaling (i.e. stick with one generic
SecurityParametersContext).  So given that, what I assumed is that
something like the following would happen:

1) In an early action as you proposed (for error handling purposes), you
had something like this in pseudo code:

if (effectivelyEncryptAssertion() || effectivelyEncryptNameID() ||
effectivelyEncryptAttribute()) {
  EncryptionParameters params = resolveEncryptionParams(.... )
  storeEncryptionParams(params, relyingPartyContext)
}

Meaning basically pre-resolve the params if you know you're going to
encrypt. (Same for signing btw).

2) in the later actions that do the encryption e.g. Assertions:

if (effectivelyEncryptAssertion()) {
  EncryptionParameters params = getEncryptionParams(relyingPartyContext)
  encryptAssertion(assertion, params)
}




>
> I don't know what you have in mind yet as Criteria for the resolvers, but
> I'm assuming that we'd need a way to signal the "type of encryption"
> (Assertion, NameID, Attribute) for it to resolve the parameters if the
> intention is to bury whether to encrypt it all into that resolution
> process.


No, I hadn't thought of anything like that.  I wasn't intending for the
-Resolvers to eval stuff that is really IdP-specific notions of
configuration, for profiles, etc.  What I have meant by "IdP security
configuration" evaled in the resolvers was really multiple instances of
-Configuration (e.g. EncryptionConfiguration), some of which are coming
from layers in the IdP.  They are arrayed in some order-of-precedence
with others from say OpenSAML (e.g. global library defaults).  But
hadn't considered taking into account for example the encryptAssertion
and signResponse kind of flags.   Instead my thought was that the IdP
evals those flags, and then if it's going to do that particular
cryptographic op, it calls the appropriate resolver with the appropriate
inputs to resolve the -Parameters.

I'll do more writeup when this is more solid, but right now I see 2-3
obvious runtime inputs to the -Resolvers as Criterion instances:

1) one that takes a list (or probably a varargs) of the appropriate
-Configurations
2) for the SAML-aware specializations, one that takes a RoleDescriptor
to support the algorithm support extension (for signing at least,
encryption doesn't need b/c the info will be attached already to the
credential by the MetadataCredentialResolver)
3) for niche cases, one that takes a KeyInfo "profile" name, used with
NamedKeyInfoGeneratorManager.  Always optional, and in practice would be
infrequently used.

Contrary to what I previously thought, at the moment I don't think that
we'd even have -Resolver subclasses that live in the IdP project. 
They're all in OpenSAML.  Things like the IdP-specific -Configuration
instances would just be passed at runtime as Criterion inputs.  Maybe
that changes if we identify stuff I've missed, but that's my current
thinking.

I have some pretty well-formed ideas about the -Configuration and
-Resolver components now, and how they work, and I'm working on
implementing things in draft.  Hopefully I'll have something more
concrete checked in by the end of the week so we can straw man in more
detail.


> Alternatively, we can split "whether to sign/encrypt" from "how to
> sign/encrypt" and just add predicates to the signing/encryption actions
> that determine that and fail in those actions if they have to do them but
> can't find parameters.


Yes, that's essentially what I assumed you were talking about when you
suggested not using anything other than the current single
SecurityParametersContext, with an instance living somewhere under the
RelyingPartyContext.


*************************

This may deserve eventually a separate thread, but I have thought of
some issues related to multiple RP's and key multicast for encryption. 

1) It could turn out that based on -Configurations + metadata +
whitelist/blacklist, you wind up with different resolved values for the
data encryption algorithm URI.  In general I guess you then attempt to
extract the lowest (or highest) common denominator.   But it's also
possible (based on say whitelist/blacklist values) that you could
theoretically wind up with mutually exclusive choices.  So then I'm not
sure what you do...

1A) If you have to do this data encryption algorithm URI selection for
multiple RP's, that's probably some other kind of resolver or selector
component.

2) What should happen if there are multiple RPs and encryption is
required for one of more of the SAML types, but can not resolve an
encryption key for all of the RPs?  Is that an error, or do you just not
encrypt to some them?



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://shibboleth.net/pipermail/dev/attachments/20140312/2d80b39a/attachment.html 


More information about the dev mailing list