4 Replies Latest reply on Jan 31, 2013 4:34 PM by Lucas Campbell Rossen

    Does RhoElements support PKI using X509 Client Certificates for making HTTPS requests?

      Does RhoElements support PKI using X509 Client Certificates for making HTTPS requests?

      I would like to attach client certificate from a Smart Card to the HTTP request.

      I see the documentation for Rho::AsyncHttp.get() has authentication type for "basic", but what about X509?

         :authentication => { :type => :basic, :username => "john", :password => "secret" }

      Like

         :authentication => { :type => :X509, :cert... }

       

      If so, do you have a sample?

        • Re: Does RhoElements support PKI using X509 Client Certificates for making HTTPS requests?

          Is AsyncHttp the correct approach for X509, or is there an alternate approach?

          • Re: Does RhoElements support PKI using X509 Client Certificates for making HTTPS requests?

            Hello,

             

            What we are trying to accomplish: We are trying to perform an HTTPS request to our server which requires a Client Cert.  This client cert is stored on our Smart Card (also in the Local Certificate Store).  The private key for this certificate is only stored on the smart card, not in a file.  Also a PIN is required to access the private key.  We have a .NET solution that works by pulling a specific users certificates from the Key Store, and attaches them as context of the HTTP Request; where there is a callback function that allows the TSL/SSL handshake to ignore certain warnings, like Server Name mismatch, etc.  When we perform this HTTP request the TSL/SSL handshakes wakes up our CAC card smart driver to prompt for the PIN (our application does NOT prompt for the PIN).  Once the PIN is entered and correct the TSL/SSL handshake completes and the request is authenticated and proceeds.  We would like to perform this same approach in RhoMobile.  It doesn't appear that the AsyncHTTP call allows certificates, so I have tried using the OpenSSL approach described below (source code found in the auth_rhoconnect/application.rb from x509-auth-sample).  I am having issues in that I am unsure how to set up the 'pem' variable described below.  I have tried using a cert and key that I have stored in a file, however having systax issues (I don't know how to load the files into the ssl_context.cert and ssl_context.key.  Also, I ultimately want to pull the .cert and .key from the Key Store rather than a file. 

             

            Does RhoMobile support this approach? 

             

             

             

                 def authenticate(username,password,session)

                     #assuming pem file has certificate and then private key below in pem format

                     myPemFile = "/temp/server.pem"

                     pem = File.read myPemFile                                                                               ### <-- HOW DO I set UP this 'pem' value???

                     pem_arr = pem.to_st().split("-----END CERTIFICATE-----")                                      ### NOTE: I added the 'to_st()' to your example

                     pem_arr[0] << "-----END CERTIFICATE-----"

             

                     socket = TCPSocket.new('my.secureserver.com', 4567)

                     ssl_context = OpenSSL::SSL::SSLContext.new

                     ssl_context.cert = OpenSSL::X509::Certificate.new(pem_arr[0].strip)

                     ssl_context.key = OpenSSL::PKey::RSA.new(pem_arr[1].strip)

                     ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)

                     ssl_socket.sync_close = true

                     ca_cert = OpenSSL::X509::Certificate.new(File.open("CA.crt"))

                     if ssl_socket.connect

                      ssl_socket.puts("GET / HTTP/1.1")          ### NOTE: <--- This causes systax error (private method 'puts' called) - SO I changed it to ssl_socket.syswrite, then I get http code 400

                      ssl_socket.puts("")

                      return true

                     else

                      puts "socket failed to connnect"

                       return false

                     end

                 end

             

            NOTE: When using ssl_socket.syswrite, I get a server return code of "400 Bad Request", which implies that it could not digest the "mal-formed" header I sent?  Does it have to do with the fact that I am using .syswrite vs .puts?  Your example shows .puts, however that method does not exist on OpenSSL::SSL::SSLSocket.

             

            Questions:

               How do I properly set up the ssl_context (cert and key)?

               How do I properly write and read from the ssl_socket with a well formed header?