Personal tools

MSNP15:SSO

From MSNPiki

MSN Protocol Version 15

Overview · Changes · Single Sign-On · Ticket Tokens
New features: Locations · Roaming Content


Contents

RPS/SSO Authentication

When you authenticate with MSNP15, you will notice that the USR command has changed slightly. Here is the new format:

Abstract

Client: USR <TrId> SSO I <email>\r\n
Server: USR <TrId> SSO S <policy> <base64 encoded nonce>\r\n
Client: USR <TrId> SSO S <ticket> <base64 encoded response structure>\r\n
Server: USR <TrId> OK <email> <verified> 0\r\n

Example

Client: USR 10 SSO I buddy@live.com\r\n
Server: USR 10 SSO S MBI_KEY_OLD E4Fhehbe0q2Je+SUSp7IRnJV+rN4uME75ljIpUjIZ1Si+DgmrfuiIL+AFmkMA6Wv\r\n
Client: USR 11 SSO S t=... HAAAAAEAAAADZgAABIAAAA...\r\n
Server: USR 11 OK buddy@live.com 1 0\r\n

After you receive the first "SSO S" command, you should take your given policy and connect to https://login.live.com/RST.srf.

Remark: For the account which ends up with @msn.com, this should be https://msnia.login.live.com/pp550/RST.srf.

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
   xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
   xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"
   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
   xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
   xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc"
   xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">
   <Header>
       <ps:AuthInfo
           xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL"
           Id="PPAuthInfo">
           <ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>
           <ps:BinaryVersion>4</ps:BinaryVersion>
           <ps:UIVersion>1</ps:UIVersion>
           <ps:Cookies></ps:Cookies>
           <ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>
       </ps:AuthInfo>
       <wsse:Security>
           <wsse:UsernameToken Id="user">
               <wsse:Username>email@live.com</wsse:Username>
               <wsse:Password>PasswordGoesHere</wsse:Password>
           </wsse:UsernameToken>
       </wsse:Security>
   </Header>
   <Body>
       <ps:RequestMultipleSecurityTokens
           xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL"
           Id="RSTS">
           <wst:RequestSecurityToken Id="RST0">
               <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
               <wsp:AppliesTo>
                   <wsa:EndpointReference>
                       <wsa:Address>http://Passport.NET/tb</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
           </wst:RequestSecurityToken>
           <wst:RequestSecurityToken Id="RSTn">
               <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
               <wsp:AppliesTo>
                   <wsa:EndpointReference>
                       <wsa:Address>domain</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <wsse:PolicyReference URI="policy parameter"></wsse:PolicyReference>
           </wst:RequestSecurityToken>
           ...
           ...
       </ps:RequestMultipleSecurityTokens>
   </Body>
</Envelope>

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.

Some examples of sites that you can authenticate with

Domain: http://Passport.NET/tb
Policy Ref URI: -
Purpose: Unknown, but it's required for the request to succeed.
Domain: messengerclear.live.com
Policy Ref URI: <obtain from the USR command>
Purpose: Authentication for messenger.
Domain: messenger.msn.com
Policy Ref URI: ?id=507
Purpose: Messenger website authentication.
Domain: contacts.msn.com
Policy Ref URI: ?fs=1&id=24000&kv=9&rn=93S9SWWw&tw=0&ver=2.1.6000.1
New Policy Ref URI: MBI (used in WLM 8.5.1288.816)
Purpose: Authentication for the Contact server.
Domain: messengersecure.live.com
Policy Ref URI: MBI_SSL
Purpose: Unknown
Domain: spaces.msn.com or spaces.live.com
Policy Ref URI: MBI
Purpose: Authentication for the Windows Live Spaces
Domain: livecontacts.live.com
Policy Ref URI: MBI
Purpose: Live Contacts API, a simplified version of the Contacts SOAP service
Domain: storage.live.com
Policy Ref URI: MBI
Purpose: Storage REST API

The response to this query when successful, looks like this.

<S:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Header>
       There is really data here, but for space it has be removed
   </S:Header>
   <S:Body>
       <wst:RequestSecurityTokenResponseCollection
           xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
           xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust"
           xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
           xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
           xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
           xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"
           xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
           <wst:RequestSecurityTokenResponse>
               <wst:TokenType>urn:passport:legacy</wst:TokenType>
               <wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
                   <wsa:EndpointReference>
                       <wsa:Address>http://Passport.NET/tb</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <wst:LifeTime>
                   <wsu:Created>2006-12-06T05:12:10Z</wsu:Created>
                   <wsu:Expires>2006-12-07T05:12:10Z</wsu:Expires>
               </wst:LifeTime>
               <wst:RequestedSecurityToken>
                   <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"
                    Id="BinaryDAToken0"
                    Type="http://www.w3.org/2001/04/xmlenc#Element">
                       <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc">
                           </EncryptionMethod>
                       <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                           <ds:KeyName>http://Passport.NET/STS</ds:KeyName>
                       </ds:KeyInfo>
                       <CipherData>
                           <CipherValue>
                               cipher data you don't need to worry about
                           </CipherValue>
                       </CipherData>
                   </EncryptedData>
               </wst:RequestedSecurityToken>
               <wst:RequestedTokenReference>
                   <wsse:KeyIdentifier ValueType="urn:passport"></wsse:KeyIdentifier>
                   <wsse:Reference URI="#BinaryDAToken0"></wsse:Reference>
               </wst:RequestedTokenReference>
               <wst:RequestedProofToken>
                   <wst:BinarySecret>ignore this one</wst:BinarySecret>
               </wst:RequestedProofToken>
           </wst:RequestSecurityTokenResponse>
           <wst:RequestSecurityTokenResponse>
               <wst:TokenType>urn:passport:compact</wst:TokenType>
               <wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
                   <wsa:EndpointReference>
                       <wsa:Address>messengerclear.live.com</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <wst:LifeTime>
                   <wsu:Created>2006-12-06T05:12:10Z</wsu:Created>
                   <wsu:Expires>2006-12-06T13:12:10Z</wsu:Expires>
               </wst:LifeTime>
               <wst:RequestedSecurityToken>
                   <wsse:BinarySecurityToken Id="Compactn">
                       t=<ticket goes here>&p=
                   </wsse:BinarySecurityToken>
               </wst:RequestedSecurityToken>
               <wst:RequestedTokenReference>
                   <wsse:KeyIdentifier ValueType="urn:passport:compact"></wsse:KeyIdentifier>
                   <wsse:Reference URI="#Compactn"></wsse:Reference>
               </wst:RequestedTokenReference>
               <wst:RequestedProofToken>
                   <wst:BinarySecret>binary secret (you need this)</wst:BinarySecret>
               </wst:RequestedProofToken>
           </wst:RequestSecurityTokenResponse>
           <wst:RequestSecurityTokenResponse>
               <wst:TokenType>urn:passport:legacy</wst:TokenType>
               <wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
                   <wsa:EndpointReference>
                       <wsa:Address>site domain</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <wst:LifeTime>
                   <wsu:Created>2006-12-06T05:12:10Z</wsu:Created>
                   <wsu:Expires>2006-12-06T05:20:30Z</wsu:Expires>
               </wst:LifeTime>
               <wst:RequestedSecurityToken>
                   <wsse:BinarySecurityToken Id="PPTokenn">
                       t=<site ticket here>&p=<site profile here>
                   </wsse:BinarySecurityToken>
               </wst:RequestedSecurityToken>
               <wst:RequestedTokenReference>
                   <wsse:KeyIdentifier ValueType="urn:passport"></wsse:KeyIdentifier>
                   <wsse:Reference URI="#PPTokenn"></wsse:Reference>
               </wst:RequestedTokenReference>
           </wst:RequestSecurityTokenResponse>
           ...
           ...
       </wst:RequestSecurityTokenResponseCollection>
   </S:Body>
</S:Envelope>

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 and your Binary secret, we need to create a structure of information to send back to the server. The C++ style structure look like this:

typedef struct tagMSGRUSRKEY
{
       unsigned long uStructHeaderSize; // 28. Does not count data
       unsigned long uCryptMode; // CRYPT_MODE_CBC (1)
       unsigned long uCipherType; // TripleDES (0x6603)
       unsigned long uHashType; // SHA1 (0x8004)
       unsigned long uIVLen;    // 8
       unsigned long uHashLen;  // 20
       unsigned long uCipherLen; // 72
// Data
       unsigned char aIVBytes[8];
       unsigned char aHashBytes[20];
       unsigned char aCipherBytes[72];
}MSGUSRKEY;

Note that these values are all Little-Endian. unsigned long is 4 bytes.

If you use the default values that messenger give, the sizes of the BYTE arrays will be correct, if you do not use the default values, you'll have to adjust properly.

aIVBytes is an array of random data that is used in the encryption process.

Here's how to create the hashes: Base64 decode your nonce. Derive a SHA-1/TripleDES key from the decoded data. Use that key to perform this pseudo-code.

hash1 = SHA1-HMAC("WS-SecureConversationSESSION KEY HASH")
hash2 = SHA1-HMAC(hash1, "WS-SecureConversationSESSION KEY HASH")
hash3 = SHA1-HMAC(hash1)
hash4 = SHA1-HMAC(hash3,"WS-SecureConversationSESSION KEY HASH")

Take all 20 bytes from hash2 and the first 4 bytes from hash4. Store that in 'key2' Now do the samething only this time use the string "WS-SecureConversationSESSION KEY ENCRYPTION" and store it in 'key3'

No generate 8 bytes of random data. In your encryption library, set IV as these bytes, and set the mode to CBC.

Import key2 and create a new SHA-1 HMAC hash. Import key3. Use the HMAC hash and the imported key3 to TripleDES encrypt/hash the data. Fill In the structure above and the base64 encode it.

Now take the base64 encoded structure and send it back to the server. If you've done everything right, you should received the OK reply.

Test Values

Nonce: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
Binary Secret: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
IV(hex): 00 00 00 00 00 00 00 00
Result (newline added readability): HAAAAAEAAAADZgAABIAAAAgAAAAUAAAASAAAAAAAAAAAAAAA7XgT5ohvaZdoXdrWUUcMF2G8OK2JohyY
cK5l5MJSitab33scxJeK/RQXcUr0L+R2ZA9CEAzn0izmUzSMp2LZdxSbHtnuxCmptgtoScHp9E26HjQVkA9YJxgK/HM=
Nonce: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
Binary Secret: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
IV(hex): 00 00 00 00 00 00 00 00
Result (newline added readability): HAAAAAEAAAADZgAABIAAAAgAAAAUAAAASAAAAAAAAAAAAAAAywfWRZVnRRZTqPkW6HBIrOmPuYiFbzcpv
YmP2QzhpH+VdKwtqUTt/gdbDqlMZvR1o7ve9ex44otMOxYtnNYIQ+lfoj+PKcsHT+T7GA1hfMsTVbGqoYYe3B5/WW0=


Code Examples

C (Linux) sso
VC++ (MFC) MBI Hash Example
C++ QT4 QCA - SSO Crypto Example
VB .NET: MBI Code
Java: ticket and hash code

References

Zoronax's Blog
MSNP15 authentication scheme REd
MSNP15 繁體中文相關資訊

Reference