Before you can send any provisioning commands to Broadsoft Broadworks via the OCI-P interface, you first need to open a session. In this post, I’m going to walk you through the basic steps to open a session.
To open a session, the user must log in. Here an illustration of the overall login sequence.
So we need to implement the following parts:
- Generate a unique session ID.
- Send authentication request to retrieve a nonce.
- Generate a salted MD5 hash of user’s password and the nonce retrieved.
- Send login request using salted password hash and username along with session ID.
After successful login, you need to send the session ID along with every subsequent OCIMessage. Also, keep in mind that OCI-P sessions are bound to the socket creating them.
Let’s take a closer look at each step with some Java pseudo code. As shown in the sequence diagram above, you need the user’s username and password. The login process doesn’t differ for the type of user. So you can use this implementation if you want to login as a normal user or as an administrator user on service provider level.
Step 1: Generate unique session ID
You first need to generate a unique session ID. The OCI-P specification only defines that a session ID must be a XSD normalized string and that you are responsible for ensuring it is unique. You could now spend days on coming up with a perfect algorithm generating unique session IDs across a cluster of application servers. Or you could just be a pragmatic programmer instead and use a UUID :-)
All major programming languages provide a built-in library to generate UUIDs. Use it!
Step 2: Send authentication request and get nonce
You now got a shiny new session ID. So it is time to talk to Broadworks by sending an AuthenticationRequest. From now on, you need to include the session ID in every OCIMessage you send. So make sure you run all request through a central place in your code to add it.
As part of the AuthenticationRequest, you are also sending the userId (i.e. username) of the user going to login. In the response, a nonce is returned. We use this nonce in the next step to generate a salted hash of the user’s password.
Step 3: Generate salted password hash
Nowadays, it is common sense to not send plain passwords to a backend system, but instead only a hash of it. Converting a hash back into a password is impossible. However, password hashes are vulnerable against dictionary attacks where an attacker pre-computes hashes of possible passwords and checks if the captured hash matches any pre-computed hash.
To prevent dictionary attacks, salted hashes are used. Before computing the password’s hash, another string is added to it. This string is known as salt or nonce. The hash is computed of the now salted password.
OCI-P implements this approach with a little twist:
- compute SHA1 hash of password and get HEX representation
- combine nonce with SHA1 hash separating both by a colon
- compute MD5 hash of salted password hash and get HEX representation
This sounds complicated, but can be achieved in 3 lines of code if using Apache Commons Codec library:
The signedPassword is the incredient needed to send the login request in the next and final step.
Step 4: Send OCI-P login request
We are just a single OCIMessage away from establishing a OCI-P session. We need to send a LoginRequest14sp4 request along with the userId (i.e. username) and signedPassword we just computed in the previous step.
As a result, we should receive a LoginResponse14sp4 containing some useful information about the signed-in user. If login fails, Broadworks will return one of the following error codes:
- 4900 – invalid userId provided (i.e. user doesn’t exist)
- 4962 – invalid password
If you always receive error 4962, you need to review your code generating the signedPassword again.
After successful login, you only need to keep the session ID and userId. You can and should forget the nonce, password, and signedPassword so that those items are also cleared from memory. Just include the session ID in any sub-sequent OCIMessage you send. To cancel a session, either close the socket you are using or send a LogoutRequest, but don’t be surprised if you receive no response for it. But that’s a different topic for a different post :-)
Get in touch!
Want to learn more? Got questions? Something to add?Contact us!