SSL [X.509] Authentication in Rails?

Been doing some research but haven’t been able to determine much - has
anyone had any experience parsing incoming [on the request] x.509
certificates? Specifically, getting name, CA, etc. Here’s how you do in
Java Servlets for reference:

X509Certificate[] certs = (X509Certificate[])
request.getAttribute(“javax.servlet.request.X509Certificate”);

Thanks.

Maybe another way to phrase the question is to say 'how do you get at
the request object?

Brez! !! wrote:

Maybe another way to phrase the question is to say 'how do you get at
the request object?

You can probably find what you’re looking for in the OpenSSL wrapper
library (lightly documented, but the source code is in the Ruby distro
of course). I’m not aware that there is anything in pure Ruby to do what
you want, but others are more knowledgeable than I am. If it turns out
there is nothing, I’d be interested in adding it as an adjunct to the
Net::LDAP library. (I’ve written a lot of X.509 processors in C over the
years.) If anyone is interested, let me know here.

Net::LDAP library. (I’ve written a lot of X.509 processors in C over the
years.) If anyone is interested, let me know here.

Thanks for the suggestions , I’ll chk them out. Also found this progject
in relation to rails and your LDAP project in particular:

http://rubyforge.org/projects/railspki/

Unfortunatly it doesn’t do what I’m looking to accomplish. Actually what
I need has less to do with actual SSL and more to do with the request
object supporting the cert chain [and subsequentially rails having
access to it] - I will review it more for some hints tho. I’m also going
to look at Jetty’s implementation of it as part of the servlet spec.
Regardless tho, I’ll post up whatever I find / write it as plugin…
Thanks again Francis.

Someone correct me if I am wrong, but I think a client certificate is
only sent to the server if the server requests one, and how the
certificate is made available probably varies by webserver. I know
for example with modssl and apache the certificate is an environment
variable in the CGI namespace.

I don’t know if lighttpd has client certificate support, and if so if
that information is available via the fastcgi environment. Might want
to check out pound also, I believe it supports client certs, and it’s
probably a better alternative since it can probably forward the
certificate to something like mongrel. I’m guessing webrick is a dead
end, I haven’t even seen complete directions on how to enable basic
ssl with webrick.

If you make any headway on this please do post, I’ve been meaning to
look at this myself but it just hasn’t been a top priority.

Also, for parsing certificates you might want to look here:

http://dataspill.org/articles/2005/01/10/goofing-off-simple-extensible-certificate-authority

I used this as a base to redo our again CA which was written in perl.
There is code in there to parse X509 certificates. I think most of
what you might be looking for is in lib/pki_helper.rb.

Chris

snacktime wrote:

Someone correct me if I am wrong, but I think a client certificate is
only sent to the server if the server requests one, and how the
certificate is made available probably varies by webserver. I know
for example with modssl and apache the certificate is an environment
variable in the CGI namespace.

I don’t know if lighttpd has client certificate support, and if so if
that information is available via the fastcgi environment. Might want
to check out pound also, I believe it supports client certs, and it’s
probably a better alternative since it can probably forward the
certificate to something like mongrel. I’m guessing webrick is a dead
end, I haven’t even seen complete directions on how to enable basic
ssl with webrick.

If you make any headway on this please do post, I’ve been meaning to
look at this myself but it just hasn’t been a top priority.

Correct - Apache can make a cert optional or require it… Yea I’ll chk
out pound [thanks] - most, if not all, of these servers support passing
cert chains - what I need to produce is having the cert’s information
available as part of an ActionController [primarily for the
metadata/‘identification,’ not security, and *not to do any actual
authentication/revocation/etc - this is stuff that most servers already
provide, and is arguably an issue of transport and not within scope of
what rails, as an application framework, ought to provide].

Thanks

If you make any headway on this please do post, I’ve been meaning to
look at this myself but it just hasn’t been a top priority.

Ok - made some headway… I’m using Oracle’s OHS aka Apache because it
comes with FastCGI installed, setup, etc. As far as I know it should be
identical to Apache config, etc. [Lighttpd, Pound, et al same basic
principles should apply but you’ll have to sort out the details] –

The solution was pretty straightforward in the end, essentially make
sure that the SSL Environmental Variables are available to CGI/FastCGI
by editing your ssl.conf file to include:

SSLOptions +StdEnvVars

There’s other options available as well see ssl.conf for specifics…

Once variables are available, they magically appear in your
ActionController request object, e.g. to get the subject line of a
client’s cert:

request.env[‘SSL_CLIENT_S_DN_CN’]

And that’s it… it’s running now and I’m using the subject line of the
cert [with ID] to log people in [as opposed to a login/password box,
etc]… i.e. discovering their ‘identity’… not necessarily a valid
security solution [but this could be accomplished using revocation, etc
as part of Apache- regardless, any solution is going to be somewhat
dependent on the environment that it runs in.]

Here’s a list of all the SSL Env Vars for ref:

HTTPS SSL_CLIENT_M_VERSION SSL_SERVER_M_VERSION
SSL_CLIENT_M_SERIAL SSL_SERVER_M_SERIAL
SSL_PROTOCOL SSL_CLIENT_V_START SSL_SERVER_V_START
SSL_SESSION_ID SSL_CLIENT_V_END SSL_SERVER_V_END
SSL_CIPHER SSL_CLIENT_S_DN SSL_SERVER_S_DN
SSL_CIPHER_EXPORT SSL_CLIENT_S_DN_C SSL_SERVER_S_DN_C
SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_ST SSL_SERVER_S_DN_ST
SSL_CIPHER_USEKEYSIZE SSL_CLIENT_S_DN_L SSL_SERVER_S_DN_L
SSL_VERSION_LIBRARY SSL_CLIENT_S_DN_O SSL_SERVER_S_DN_O
SSL_VERSION_INTERFACE SSL_CLIENT_S_DN_OU SSL_SERVER_S_DN_OU
SSL_CLIENT_S_DN_CN SSL_SERVER_S_DN_CN
SSL_CLIENT_S_DN_T SSL_SERVER_S_DN_T
SSL_CLIENT_S_DN_I SSL_SERVER_S_DN_I
SSL_CLIENT_S_DN_G SSL_SERVER_S_DN_G
SSL_CLIENT_S_DN_S SSL_SERVER_S_DN_S
SSL_CLIENT_S_DN_D SSL_SERVER_S_DN_D
SSL_CLIENT_S_DN_UID SSL_SERVER_S_DN_UID
SSL_CLIENT_S_DN_Email SSL_SERVER_S_DN_Email
SSL_CLIENT_I_DN SSL_SERVER_I_DN
SSL_CLIENT_I_DN_C SSL_SERVER_I_DN_C
SSL_CLIENT_I_DN_ST SSL_SERVER_I_DN_ST
SSL_CLIENT_I_DN_L SSL_SERVER_I_DN_L
SSL_CLIENT_I_DN_O SSL_SERVER_I_DN_O
SSL_CLIENT_I_DN_OU SSL_SERVER_I_DN_OU
SSL_CLIENT_I_DN_CN SSL_SERVER_I_DN_CN
SSL_CLIENT_I_DN_T SSL_SERVER_I_DN_T
SSL_CLIENT_I_DN_I SSL_SERVER_I_DN_I
SSL_CLIENT_I_DN_G SSL_SERVER_I_DN_G
SSL_CLIENT_I_DN_S SSL_SERVER_I_DN_S
SSL_CLIENT_I_DN_D SSL_SERVER_I_DN_D
SSL_CLIENT_I_DN_UID SSL_SERVER_I_DN_UID
SSL_CLIENT_I_DN_Email SSL_SERVER_I_DN_Email
SSL_CLIENT_A_SIG SSL_SERVER_A_SIG
SSL_CLIENT_A_KEY SSL_SERVER_A_KEY
SSL_CLIENT_CERT SSL_SERVER_CERT
SSL_CLIENT_CERT_CHAINn
SSL_CLIENT_VERIFY

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs