Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Wednesday, January 06, 2010

Tomcat SSL configuration. Import certificate chain to keystore (emit error “keytool error: java.lang.Exception: Input not an X.509 certificate”)

I seldom use mutual authentication in the context of SSL. Recently, in our derived project (integration with MyOSG), we need to enforce use of mutual SSL authentication.

Enable client authentication in Tomcat server

At first, I enabled it in tomcat server configuration file

An important option is "clientAuth”.
Note: before this step, I have generated and imported a certificate for tomcat server.

Import user certificate

This is done by the end users who wish to access the protected services. They need to

  1. import received certificate from CA to their browser
    Actually, both the private key and certificate need to be imported.
    For Firefox, only pkcs#12 format is supported.  If the private key has been imported, you just need to import certificate whose format can be PEM, binary, etc.
  2. import server’s certificate into trusted ca repository in browser
    The aim is to make the browser trust the certificate received from remote service. It’s useful when the service certificate is not issued by a well-known top-level CA.

After those two steps, I directed my browser to the service url. Unfortunately, I got the following error:

image

After digging a little bit, I found out the cause was that tomcat server does not trust certificate sent by my browser. So the solution is simple: add certificate chain related to my certificate to tomcat keystore.

I got the certificate chain from the issuer of my certificate. It’s in PKCS#7 format and contains two certificates in the file. You can view PKCS7-formatted file using following commands:
1) openssl pkcs7 -print_certs -text < pkcs7_cert_chain.pem
2) keytool -printcert –file pkcs7_cert_chain.pem

When I tried to import it into keystore using following command
    keytool -importcert -file pkcs7_cert_chain.pem -keystore keystore -alias test-cert –trustcacerts
I got the following error
    keytool error: java.lang.Exception: Input not an X.509 certificate
I am sure keytool can recognize the file because the following command prints out information in the file correctly.
    keytool -printcert –file pkcs7_cert_chain.pem

Solution

After reading keytool manual carefully, I found following statements:

Importing a New Trusted Certificate

    Before adding the certificate to the keystore, keytool tries to verify it by attempting to construct
    a chain of trust from that certificate to a self-signed certificate (belonging to a root CA), using
    trusted certificates that are already available in the keystore.

Importing a Certificate Reply

    ……

      o If the reply is a PKCS#7 formatted certificate chain, the chain is first ordered (with the user
        certificate first and the self-signed root CA certificate last), before keytool attempts to
        match the root CA certificate provided in the reply with any of the trusted certificates in the
        keystore or the "cacerts" keystore file (if the -trustcacerts option was specified). If no match
        can be found, the information of the root CA certificate is printed out, and the user is
        prompted to verify it, e.g., by comparing the displayed certificate fingerprints with the fin-
        gerprints obtained from some other (trusted) source of information, which might be the root CA
        itself. The user then has the option of aborting the import operation. If the -noprompt option
        is given, however, there will be no interaction with the user.

So, what I was doing is to import a trusted certificate chain. This is not allowed directly. keytool just accepts cert file that includes a single certificate.

So I extracted two certificates into two files, and fed them into keytool one by one. Details:
Use command
    openssl pkcs7 -print_certs < pkcs7_cert_chain.pem
to display the two certificates in the original pkcs7 file. And then copied and pasted each cert into an individual file.

Note: when you are importing a certificate reply from a CA, certificate chain can be imported directly into keystore. However, before doing that, you must guarantee that the corresponding private key has already been imported in to the same keystore.

Monday, June 15, 2009

Key generation using OpenSSL

Generate RSA public/private key pair

Generate private key:
openssl genrsa -out private_key.pem 1024
Convert private key to PKCS8 format:
openssl pkcs8 -topk8 -in privkey.pem -nocrypt
Generate public key:
openssl rsa -pubout -in private_key.pem -out public_key.pem
Read Base64 Encoded private key
openssl rsa -text -in private_key.pem

Generate Self-Signed certificate

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout private_key.pem -out cert.pem

Thursday, June 04, 2009

2-legged OAuth System Tutorial

Use Cases:

(1) A user wants to grant data access priviledges to a third-party application.
  Here three parties are involved:
  User
    the end user
  Third-Party application
    It wants to manipulate user's data on behalf of the user.
  Service Provider
    a remote application that provides the real service.

  The procedure of granting priviledges:
  (I) complete steps described in section
      (Provider side) > (For regular users)
  (II) complete steps described in section
      (Consumer side) > (For regular users)
  Note: the public key uploaded in step (I) and private key uploaded in
  step (II) must match.

(2) A user wants to develop a third-party application for our service.
  (I) Register the application by completing steps described in section
      (Provider side) > (For thrid-party application developers)
  Now, the application can use the service.

  (II) To make use of built-in third-party application, complete steps
    described in section
      (Consumer side) > (For application manager)

(3) A user wants to use a deployed and configured third-party application.
  (I) Go to http://yourhost:yourport/oauthConsumer-0.1
  (II) Login with existing account and you will be directed to page 'account.jsp'
  (III) All supported third-party applications are listed under section
  (Available service providers). Click a link to use the corresponding
  application.

 

Consumer side

For regular users

Steps
  (1) Go to http://yourhost:yourport/oauthConsumer-0.1
  (2) Register a new account or log in with existing account
  (3) Go to account.jsp (you should be automatically directed to this page)
  (4) If it is the first time for the user to request an OAuth protected
      service via client application, the user should do some configurations.
      Click the link "Private Key Binding And Service Provider Setting"
  (5) On this page, user can do some configurations
    (5.1) UserId binding
      This setting binds local user Id to user Id used by remote service.
      For example, if a user wants to access remote Yahoo flickr service
      through a third-party app, the local user Id is the user id used by the
      third-party app and it is bound to the user Id used by Yahoo Flickr.
    (5.2) Private key setting
      Possession of private key makes the third-party app be able to access
      remote service on behalf of the user.

For application manager

Actually, only administrators should have the priviledge to manage third-party
application registry. But currently user management system is simple and all
users have the same priviledges.
Steps
  (1) Go to http://yourhost:yourport/oauthConsumer-0.1
  (2) Register a new account or log in with existing account
  (3) Go to account.jsp (you should be automatically directed to this page)
  (4) Click the link "Attributes of available service providers"
  (5) Now, the user can register a new third-party app, remove an existing
      registration and modify existing registration information.

Provider side

Currently, only one service is offered - echo service.

For regular users

Steps
  (1) Go to http://yourhost:yourport/oauthServer-0.1
  (2) Register a new account or log in with existing account
  (3) Go to account.jsp (you should be automatically directed to this page)
  (4) Click the link "Certificate Setting"
  (5) On this page, user can do some configurations
    (5.1) Third-party app priviledge setting
      Users can specify which third-party applications are allowed to access
      their data.
    (5.2) Certificate upload
      Upload your X.509 certificate (of PEM format).

For thrid-party application developers

Steps
  (1) Go to http://yourhost:yourport/oauthServer-0.1
  (2) Register a new account or log in with existing account
  (3) Go to account.jsp (you should be automatically directed to this page)
  (4) Click the link "Developer Account"
  (5) Type information of the third-party application that is to be registered.
      A consumer key/secret pair is generated as well.

Use of Public/Private key pair

There are two types of private/public key pair:
(1)
    One is used to guarantee integrity of messages transmissioned between
  third-party application and service provider.
    So for service provider, the public key is published. If a third-party
  application wants to access the service, it should use the published public
  key to sign outbound messages.
(2)
    The other is owned and deployed by end user. The goal is to provide a way so
  that third-party application can use backend service on behalf of user
  without user involvement.
    So this pair is owned by end user. To deploy the key pair:
  (*) upload the public key to service provider
  (*) upload the private key to third-party application
    Then the third-party application uses the private key to sign part of the
  message (The whole message is signed using pub/priv key pair described in
  bullet 1).

OAuth message

    ___________________________________________________________
   |                                                           |
   |     _________________________________________________     |
   |    |   ___________________________________________   |    |
   |    |  |  ______________       _________________   |  |    |
   |   P|  | |              |     |                 |  |  |    |
   |   a|  | | Payload 2    |     |  Signature (2)  |  |  |    |
   |   y|  | |______________|     |_________________|  |  |    |
   |   l|  |___________________________________________|  |    |
   |   o|                                                 |    |
   |   a|   ___________________________________________   |    |
   |   d|  |                                           |  |    |
   |    |  |                Other parts                |  |    |
   |   1|  |___________________________________________|  |    |
   |    |_________________________________________________|    |
   |     _________________________________________________     |
   |    |                                                 |    |   
   |    |       Signature (1)                             |    |
   |    |_________________________________________________|    |
   |                                                           |
   |___________________________________________________________|

In above figure, <Signature (1)> is calculated using key described in bullet 1. <Signature (2)> is calculated using key described in bullet 2.