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.

Tuesday, June 02, 2009

H2 Exception "Database may be already in use: Locked by another process"

I wrote two Java web servlet apps (oauth consumer app, and oauth server app) both of which rely on H2 as database engine. I want H2 to be run in embedded mode instead of server mode. According to the official document, following statement should be added to web.xml

<listener>
    <listener-class>org.h2.server.web.DbStarter</listener-class>
</listener>

This class has methods that listen to the servlet context event (context initialization, context destroyed).

When I deploy just one of the two web apps to tomcat, it works fine. When I deploy both of them, following exception is thrown

Exception in thread "main" org.h2.jdbc.JdbcSQLException: Database may be already in use: Locked by another process. Possible solutions: close all other connecti on(s); use the server mode [90020-63]

I am 100% sure that those two apps use different databases. To make myself 200% sure that my code does not create or use additional databases unintentionaly, I rechecked my code many many times. But my code looks just fine. So I doubted it may be because of the H2 database engine.
Then I used command 'lsof' to list opened files by tomcat java process. Surprisingly, a database named 'test' is created under my home directory.
I reread the document http://www.h2database.com/html/tutorial.html#web_applications, and I got what I missed before.

For details on how to access the database, see the file DbStarter.java. By default the DbStarter listener opens an embedded connection using the database URL 'jdbc:h2:~/test', user name 'sa', and password 'sa'.

Code of class DbStarter can be accessed at http://code.google.com/p/h2database/source/browse/trunk/h2/src/main/org/h2/server/web/DbStarter.java.
I am just curious about why a default database is created by class DbStarter.

Solutions
(1) remove the listener declaration in web.xml
In other words, remove
    <listener> <listener-class>org.h2.server.web.DbStarter</listener-class> </listener>
(2) change url of created database.

  <context-param>
    <param-name>db.url</param-name>
    <param-value>jdbc:h2:your_new_db_url</param-value>
  </context-param>