< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate] Security class and client-side authentication (longish)


Sorry this thread is so long but there is some good stuff in here ....


>> I think we should consider a design meeting to sort some of this out.
> Sounds good.  How should we go about this?

Seems like it would be an excellent topic for a coding session. Fix the TLS
and S/MIME credential handling in the stack and include support for fetching
certificates.

I think we need to figure out a time and place when people can make it. I
would not be able to do it until after Nov 13 (end of IETF)


This stuff is pretty hard to get right, I don't mind that we can override
and pass stuff in, but, I would like it so that for normal programs, all the
hard TLS security stuff happens for them in the stack.

> 
>> 
>> Clients needs to be able to store fingerprints of non CA signed servers
>> certs they are willing to trust
> 
> Agreed, but this may be outside the purview of reSIProcate.  I'd hate to see a
> lot of x509 and TLS clutter in the midst of all the other stuff.
> 

Well, things need to be able to do this - I'd rather push the complexity to
one place in the Security Object in resiprocate and not have the
applications try and directly have to deal with it all

>> 
>> 
>> On 10/22/04 5:51 PM, "Bob Bramwell" <bob@xxxxxxxxxx> wrote:
>> 
>> 
>>> This note is part reality check and part change proposal.  Your constructive
>>> feedback will be most welcome.
>>> 
>>> I am trying to set things up to allow TLS connections to do client
>>> authentication.

Just checking we mean the same thing my client authentication. This means
something acting as a TLS server can get the peerName of the client that
connected to it when the client does mutual TLS.

>>> There are a number of things, notably in the Security
>>> class,
>>> that will need to change to accomodate this.
>>> 
>>> At present a Security object has two public certificates associated with it:
>>> its 
>>> publicCert and its publicIdentityCert.  The former is used as the
>>> certificate
>>> presented to a TLS client when it connects to a TlsConnection created in
>>> server 
>>> mode.  The latter only appears to be used for signing stuff (computeIdentity
>>> and 
>>> checkIdentity functions).  No provision is made for a client side
>>> certificate
>>> per se. 
>> 
>> 
>> uhmm the PublicCert would be used for this
> 
> Well, maybe not.  At present the PublicCert is used as the server certificate.
> If we have a situation where the transport is being used as a TLS client and
> the 
> server requires mutual authentication, we *may* want a separate client side
> certificate, mightn't we?  I would have thought that situation might arise in
> practice.
> 
I don't think I understand the exmaple yet (just being slow). You mean you
have a sip server that has one port, that when you do a TLS connection to
it, it claims that it is "a.com" yet this same server also makes connection
to some other systems where it does mutual TLS and claims that it is "b.com"

Is this the example?

This would have to be on two separate ports (ie TLS transports) and each TLS
transport can have it's own name and cert. I thought this had been working
for a long tiem so that people could have a proxy that could act for
multiple virtual dcomains.

>> 
>> 
>>> However, if the Security object is not actually going to be used to
>>> checkIdentity or computeIdentity (these functions do not actually appear to
>>> be
>>> called anywhere by code in the reSIProcate source tree) the
>>> publicIdentityCert
>>> *could* be overloaded to act as a client certificate.
>>> 
>>> Question:  *should* the publicIdentityCert be overloaded, or should a
>>>            different certificate be attached to the Security object for
>>>            this purpose?
>> 
>> 
>> No the identity is claims is wrong. It is going to assert something like
>> "fluffy@xxxxxxxxx" not "host22.cisco.com"
> 
> Fair enough, although it is unclear to me that a Security object will ever be
> used *both* for TlsTransport certificates *and* for S/MIME signing.
> 

True enough - this may be a part we want to refractor. Originally the
security object was singleton then it got change - perhaps we need a
DomainSecurity and UserSecurity as two separate objects

>> 
>> 
>>> When a Security object is created it is either a server or a client; this is
>>> recorded in the mTlsServer member variable.  When a Security object is used
>>> (e.g. by TlsConnection) to obtain an SSL context (using getTlsCtx) the
>>> argument 
>>> isServer is passed in the call.  Why does this need to be specified in two
>>> different places?  What problem is it designed to solve?  The mTlsServer
>>> member 
>>> variable is only used in getTlsCtx, and it is far from clear what is
>>> supposed
>>> to 
>>> happen if mTlsServer and isServer have different values.
>> 
>> 
>> One can be a server, but not a tlsServer meaning you can act as a server but
>> you can not accept incoming TLS connections.
> 
> OK... I'll have to digest that one.
>> 
>> 
>>> Considering the situation when a TlsTransport is used both as a server and
>>> as
>>> a 
>>> client, it would be convenient to have a Security object that returned a
>>> different CTX depending on the role.
>> 
>> 
>> How would the TLS context be different for the two roles?
> 
> Viz. my comment following "uhmm the PublicCert would be used for this"
> earlier, 
> I think (and my understanding may be deeply flawed here) that one *might* want
> a 
> "client context" to have different certificates from a "server context".
> 

We might just be talking about different things here - not sure yet

>> 
>> 
>>> It therefore seems sensible to remove
>>> the 
>>> Security constructor tlsServer argument and the mTlsServer member variable
>>> altogether.
>>> 
>>> Question: *should* the Security::mTlsServer variable be removed (and all
>>> that
>>>           that implies)?
>>> 
>> 
>> 
>> You might be right that this is exactly the right thing to do but I have
>> certainly not got my head wrapped around what you are talking about yet
> 
> Did my earlier inline comments help?  We can bop this around offline if you
> think it might be useful.

we might need a quick phone call - my cell is 408 421 9990 if you  can catch
me before 9:30 your time today

> 
>>  
>> 
>>> The Security object only ever creates one SSL_CTX which it stashes in the
>>> ctxTls 
>>> member variable.  At present, therefore, if a Security::getTlsCtx call was
>>> made 
>>> in "client" mode before a later call in "server" mode, the SSL_CTX provided
>>> to
>>> the server would have no certificate information.  This seems entirely
>>> broken,
>>> and probably reinforces the case for maintaining at least two SSL_CTX's -
>>> one
>>> for each role.
>>> 
>> 
>> 
>> I think there is confusion about server and client mode - and I may be
>> confused on how I remember it being and how it really is - server means you
>> have a certificate. client mode means you don't. Perhaps these are named
>> terribly wrong
>> 
> 
> At present you are mostly correct, give or take the fact that there are still
> two places you have to specify whether or not this is a server side Security
> object.  My original commentary is not quite correct.  Whether or not a
> certificate is installed is determined by the setting of mTlsServer,
> effectively 
> when the object is created.  However, the scenario I described is still
> possible:
> 1. a Security object is created with tlsServer == false
> 2. getTlsCtx is called with isServer == false;
>     a client side SSL_CTX is created and cached with no certificates attached
> 3. getTlsCtx is called with isServer == true;
>     the cached SSL_CTX is returned (with no certificate)
> 
yah - I get it now - that sounds like a crappy API - we should think of
something better (which is about what I think you originally said :-)

> I'm not saying I can think of a sensible way to create these conditions, but I
> simply don't understand why the design even makes it possible.  Any
> TlsTransport 
> may end up being used in either mode, depending on how things get routed.
> 
> However, when you say "...client mode means you don't", that goes to the heart
> of the matter.  If I am going to support mutual (client side) authentication I
> *must* have a certificate (or several) and at present I haven't.
> 
Yes if you are going to do mutual TLS, right now you have to to create the
context with server = true.

>> 
>>> Finally (I hope) the TLS standard requires that a client certificate is sent
>>> only if it is signed (ultimately) by one of the acceptable CAs provided in
>>> the
>>> certificate request.
>> 
>> 
>> No self signed certs are fine to send - they just must be received carefully
> 
> Ummm... not according to the OpenSSL client_cert_cb man page, and I assume
> they 
> base their statement on an RFC of some kind (obviously I haven't looked this
> up)
> 

Well, the RFC are weird in this space and they say you MUST check the chain,
they don't say what you must do if the check fails. Think about your email
reader - say you connect with imap to a server. If the server does not have
a real cert, your client says "Sorry this certificate is bogus - do you want
to trust it" You say yes or no and after that, as long as the fignerprint
does not change, things work fine.

We want to make sure that we can do roughly the same thing for SIP.

>> 
>>> The Security class could allow the certificate selection
>>> to be performed by a caller-provided mechanism by using the
>>> SSL_CTX_set_client_cert_cb mechanism.
>>> 
>>> Question: *should* a user of the Security class be allowed to determine how
>>>           certificate selection is performed, or should this be nailed down
>>>           beyond user interference in the Security implementation?
>>> 
>> 
>> 
>> Well, let's look at what they would want to be able to control and find a
>> way to allow that
>>  
>> 
>>> I think that covers my immediate concerns; at least regarding reSIProcate,
>>> as
>>> opposed to those about world hunger, AIDS, global warming, etc..  If anyone
>>> feels like providing me with a better sense of direction I would be greatly
>>> obliged.  In particular, if there are M's I should be RTFing please let me
>>> know.
>> 
>> 
>> Glad to see some work on this and happy to help (though likely after IETF)
>> 
> 
> Thanks.  I may have to make my changes locally and see how things go.  I've
> been 
> stalling this for too long already, and at this point I simply have to make
> something work!  However, it kinda sounds like this is not a widely
> interesting 
> problem, so if I check in some backward compatible mods that are later deemed
> to 
> be a Bad Idea, I assume no one will get too upset.  NOW is the time to tell me
> if I'm wrong about that!
> 

I'm really not sure what you are trying to do on this. Can you provide a
very specific use case? I thought it already worked for what I think you are
describing.