Inside of ps:RequestMultipleSecurityTokens, you have a list of domains you want to authenticate to. You start from RST0 and you move to RST1 and so on. This allows you to get your MSPAuth and MSPProf cookies for multiple different domains all at the same time.

In your response, you will need to look for the wst:RequestSecurityTokenResponseCollection section. This section contains the list of credentials for each site you requested. If your policy reference URI contained something like MBI, MBI_SSL or MBI_KEY_OLD, the your ticket/MSPAuth&MSPProf will be in the <wsse:BinarySecurityToken Id="Compactn"> where n is the same number as the RSTn request. If the policy reference contains a string starting in a question mark (like the end of a url), your security data will be in <wsse:BinarySecurityToken Id="PPTokenn">
Technically speaking you should check the <wst:TokenType> tag.

For logging in to messenger, you will need to grab your ticket, and the contents of the <wst:BinarySecret> tag.

Computing the return value

Now that you have your ticket(nonce) and your Binary secret, we need to create a structure of information to send back to the server. The C++ style structure looks like this:

Take all 20 bytes from hash2 and the first 4 bytes from hash4. Store that in key2.
Now do the same thing only this time use the string "WS-SecureConversationSESSION KEY ENCRYPTION" (instead of "WS-SecureConversationSESSION KEY HASH") and store it in key3.

3. hash

You need to create an SHA1-HMAC hash with key2 and the nonce. Take a look at this pseudo-code:

hash = SHA1-HMAC(key2, nonce)

Let's store the data in hash

4. Pad the nonce

The official client appends to the nonce 8 bytes with the value 08 (hex)

5. Create 8 bytes of random data. These will be used in the next step.

6. TripleDes CBC encryption.

We need to use the TripleDes algorithm. Set the mode to CBC. As IV set the data obtained in step 5. As key use the key3. As input use the padded nonce (see step 4). Let's store the resulting data in a variable called encrypted_data.

7. Filling the struct

The header elements should have the value that is indicated in the comments next to them. (If you plan to use non-default values, adjust accordingly).
The aIVBytes element should be assigned the data obtained in step 5. The aHashBytes element should be assigned the data of hash (see step 3). The aCipherBytes element should be assigned the data of encrypted_data (see step 6).

8. Base64 encode the struct

Now you need to base64-encode the struct. If you're using C or C++ you have to typecast the struct variable to "char*" to be able to base64 encode it.

These base64-endoded data are the return value that you need to send to the server.