Wan-Teh Chang wrote:
> Peter Djalaliev wrote:
>> Hello,
>>
>> Given only a NSPR file descriptor, what would be the correct way to
>> see if:
>>
>> 1) TLS functionality has been layered on the file descriptor stack?
>> 2) The TLS handshake has been done with the host on the remote end of
>> the socket connection?
>>
>> For 1), can I use the PR_GetDescType() from the NSPR API?  For TCP
>> socket, I guess the type should be PR_DESC_SOCKET_TCP and for a TLS
>> socket, it would be PR_DESC_LAYERED.  Here, I am assuming that only
>> SSL can be layered on top of the TLS socket (which in my project seems
>> to be a valid assumption).
> 
> Layers other than TLS can also be layered on top of the TCP socket.
> The most reliable way to determine if the TLS functionality has
> been layered on the file descriptor stack is to call
> PR_GetIdentitiesLayer:
> http://www.mozilla.org/projects/nspr/reference/html/priofnc.html#19853
> 
> But you need the PRDescIdentity value for the TLS layer, which I don't
> think is easily available.  You can certainly use the PRDescIdentity
> value of a layer that you know for sure is TLS.
> 
> PR_GetDescType returns a PRDescType value PR_DESC_LAYERED that is
> too vague.  You'll need other information to conclude that a layer
> of the type PR_DESC_LAYERED is TLS.

NSPR maintains a table that maps layer identity name strings to
PRDescIdentity values.  There is no method that will look up the
PRDescIdentity value for an existing string in the table.  But there
IS a method that returns the layer identity name string for a given
PRDescIdentity value.

So, Peter, you should be able to traverse the stack, and for each fd,
check fd->identity, if it is not one of these reserved values:

     PR_IO_LAYER_HEAD
     PR_INVALID_IO_LAYER
     PR_TOP_IO_LAYER
     PR_NSPR_IO_LAYER

then pass fd->identity to PR_GetNameForIdentity, and then compare
the returned name string to "SSL".

I do NOT recommend that you use/call PR_GetLayersIdentity because it
will sometimes tell you the identity of the wrong layer.  Just access
fd->identity yourself.

I expect Wan-Teh will have some suggestions on how to improve that
algorithm.

>> What can I use for 2)?  I can't seem to invoke any of the SSL API
>> functions because they all use ssl_FindSocket to match the PRFileDesc*
>> to a sslSocket structure.  However, ssl_FindSocket seems to die very
>> ungracefully when it receives a non-TLS PRFileDesc and returns a
>> segmentation fault on a Linux platform.  Shouldn't ssl_FindSocket
>> return an error code instead of a segmentation fault?
> 
> ssl_FindSocket first checks the identity of the layer, so
> it seems that it should fail with the PR_BAD_DESCRIPTOR_ERROR
> if it receives a non-TLS PRFileDesc:
> http://lxr.mozilla.org/seamonkey/source/security/nss/lib/ssl/sslsock.c#220
> 
> 220 ssl_FindSocket(PRFileDesc *fd)
> 221 {
> 222     PRFileDesc *layer;
> 223     sslSocket *ss;
> 224
> 225     PORT_Assert(fd != NULL);
> 226     PORT_Assert(ssl_layer_id != 0);

I'll bet the above assertion is failing.

> 228     layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
> 229     if (layer == NULL) {
> 230         PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
> 231         return NULL;
> 232     }
> 233
> 234     ss = (sslSocket *)layer->secret;
> 235     ss->fd = layer;
> 236     return ss;
> 237 }
> 
> Do you know why ssl_FindSocket does not return from line 231 in that
> case?

If no SSL socket has been created, then ssl_layer_ID will be zero.
There has to be at least one SSL socket created somewhere, and then
ssl_layer_id will be non-zero and then ssl_FindSocket will work as
expected.

Wan-Teh, what do you think of this proposal?

I'd propose that we change PR_GetUniqueIdentity so that it looks up
the string argument in the existing table, and if found, returns the
identity for the string in the table (the index of the string pointer).
Then, if not found, it adds the string to the table and returns the new
identity value.

If PR_GetUniqueIdentity worked that way, then any software could call
PR_GetUniqueIdentity("SSL") to get the identity, even if no SSL socket
had yet been created/used.  I don't think this would happen enough that
the necessary locking would be a performance problem.

-- 
Nelson B
_______________________________________________
dev-tech-crypto mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to