On Fri, Jan 13, 2017 at 12:55 AM, Cory Benfield <c...@lukasa.co.uk> wrote:
>
>> On 13 Jan 2017, at 08:48, Nathaniel Smith <n...@pobox.com> wrote:
>>
>> The potentially-useful idea I took from this subthread was: right now
>> we have an interface with a bunch of getter/setter methods. Would it
>> make sense to *replace* that with something more declarative, like a
>> single method that takes configuration data in some sort of standard
>> format? Something very non-clever and simple, like, a dict? That seems
>> like it might both simplify the interface (e.g. the sni callback can
>> return one of these dicts instead of trying to specify OpenSSL's
>> context switcheroo weirdness; if the new dict tries to change options
>> that this particular implementation doesn't allow to be changed, then
>> it's free to error out) and be more flexible (e.g. people could write
>> validation routines that take one of these dicts and raise an error or
>> not -- having a standard format enables this but also makes it not our
>> problem).
>
> Hmm.
>
> I am extremely unsure. At the risk of sounding facetious, these two solutions 
> are *basically* isomorphic to one another: that is, an object with a bunch of 
> getters/setters is basically a dict, it’s just not something you can shove 
> arbitrary data into.
>
> That’s my main reason for preferring an object to a dict: I want to eliminate 
> a whole class of bugs that comes from accidentally doing 
> `config[’ssl_version_minimum’] = TLSv1_1` instead of 
> `config[‘tls_version_minimum’] = TLSv1_1`. Put another way, the dict approach 
> either requires that we override __setitem__ to validate all keys, or that we 
> allow typo-based errors where people accidentally get the default. The second 
> is terrifying, so we’d have to do the first, and at that point we’re 
> basically just writing an object. ;)
>
> I think the actual key here is that the “Context” object should not be 
> confused with an *actual* Context object from the backing library. That is, a 
> ClientContext() for OpenSSL does not need to compose onto it a SSL_CTX from 
> OpenSSL. It is quite reasonable for the ClientContext to just be a bucket of 
> data that manufactures SSL_CTX objects when wrap_socket is called.
>
> I don’t see why validation routines couldn’t run on Context objects directly. 
> You could even do this:
>
> class ClientValidationContext(ClientContext):
>     def validate(self):
>         “””Checks internal state and returns whether or not the context meets 
> your criteria”””
>         pass
>
> Essentially, because all code operates on the abstract objects, one of the 
> things you can do for validation is insert a *validating* implementation of 
> the abstract object. It’s exactly like a test fake, but for validation.
>
> Does that make any sense, or have I not had enough coffee yet?

I was imagining something along the lines of

ClientContext({...}).wrap_socket(...)

where ClientContext.__init__ would do the validation. Or there are
various other ways to slot the pieces together, but in general
validation doesn't need to be done incrementally; there's going to be
some place where the config dict hits the library and it can/should be
validated at that point. And before that point we get all the dict
niceties for free.

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
_______________________________________________
Security-SIG mailing list
Security-SIG@python.org
https://mail.python.org/mailman/listinfo/security-sig

Reply via email to