Difference between revisions of "SHSH Protocol"

From The iPhone Wiki
Jump to: navigation, search
m (nonce)
(A little update. The protocol description was a bit outdated.)
Line 1: Line 1:
 
Here is a description about the protocol that is used when [[iTunes]] requests the [[SHSH]] certificate from Apple. For details about what this is used for, please see the main article [[SHSH]].
 
Here is a description about the protocol that is used when [[iTunes]] requests the [[SHSH]] certificate from Apple. For details about what this is used for, please see the main article [[SHSH]].
   
This is a simple [[wikipedia:Hypertext Transfer Protocol|HTTP]] ([[wikipedia:POST (HTTP)|POST]]) request and answer. You can retry this via a [[wikipedia:Telnet|Telnet]] session or similar. The destination host is gs.apple.com (IP 17.171.36.30 [previously 17.112.176.11]) and runs on the common [[wikipedia:Hypertext Transfer Protocol|HTTP]] [[wikipedia:TCP and UDP port|port]] 80. The data is plaintext and not encoded in any way. For details about the [[wikipedia:Hypertext Transfer Protocol|HTTP]] protocol itself, please see [http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf RFC2616].
+
This is a simple [[wikipedia:Hypertext Transfer Protocol|HTTP]] ([[wikipedia:POST (HTTP)|POST]]) request and answer. You can retry this via a [[wikipedia:Telnet|Telnet]] session or similar. The destination host is gs.apple.com (IP 17.171.36.30 [previously 17.112.176.11]) and runs on the common [[wikipedia:TCP and UDP port|port]] 80. The data is plaintext and not encoded in any way. For details about the [[wikipedia:Hypertext Transfer Protocol|HTTP]] protocol itself, please see [http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf RFC2616].
   
 
===Sending data (request)===
 
===Sending data (request)===
  +
The request is actually a single XML encoded poperty list. It contains a dictionary which describes the target iOS version, restore behavior etc. Some of the required information can be taken from the BuildManifest.plist. BuildManifest contains some info about the firmware version and "BuildIdentities" dictionary. Inside it you can find two (or more?) build identities. Each of them contains the information which depends on every type of restore ("Erase" or "Update"). Some information is device-dependent (ECID, nonce) and is received from the device.
POST /TSS/controller?action=2 HTTP/1.1
 
Accept: */*
 
Cache-Control: no-cache
 
Content-type: text/xml; charset="utf-8"
 
User-Agent: InetURL/1.0
 
Content-Length: 12345
 
Host: gs.apple.com
 
 
(here comes the Plist request file)
 
   
  +
Request property list should have these properties:
===Receiving data (answer)===
 
HTTP/1.1 200 OK
 
Date: Sun, 15 Aug 2010 19:25:18 GMT
 
Server: Apache-Coyote/1.1
 
X-Powered-By: Servlet 2.4; JBoss-4.0.5.GA (build: CVSTag=Branch_4_0 date=200610162339)/Tomcat-5.5
 
Content-Type: text/html
 
Content-Length: 123456
 
MS-Author-Via: DAV
 
 
STATUS=0&MESSAGE=SUCCESS&REQUEST_STRING=(here comes the requested [[SHSH]] file)
 
   
  +
* @APTicket: Optional boolean value. If true, the server adds an [[APTicket]] to the request.
===Plist request file===
 
  +
* @BBTicket: The same for the [[BBTicket]].
'''NOTE: ''This template is only for devices other than the iPhone 4'''''
 
  +
* @UDID: Optional string value. Just request UDID. (ex. D9C1F33D-62E0-4D25-8068-F5F46FE80057).
  +
* @HostPlatformInfo: Optional(?) string value. "mac" for OS X client, "windows" for windows client (can be everything you want).
  +
* @Locality: Optional(?) string value. Language used for the error response (ex. "en_US");
  +
* @VersionInfo: Optional(?) string value. The version of 'libauthinstall' used (ex. "libauthinstall-391.0.0.1.3"). You can pass any string here.
  +
* ApBoardID: Integer value. [[BORD |Board ID]] of the target device. You can take this value from build manifest.
  +
* ApChipID: Integer value. [[CHIP|Chip ID]] of the target device. You can take this value from build manifest.
  +
* ApECID: Integer value. [[ECID]] of the target device.
  +
* ApNonce: Data value. The [[nonce]] generated by your device.
  +
* ApProductionMode: Boolean value. Always true.
  +
* ApSecurityDomain: Integer value. The use is unknown. You can take this value from build manifest.
  +
* UniqueBuildID: Data value. This is a unique identifier for every build (different even for "Erase" and "Update" types of restore). You can take this value from build manifest.
   
  +
The SHSH request also contains information about files from the [[IPSW]] (or restore bundle for [[PurpleRestore]]). They can be obtained from the 'build identity' you've chosen in the previous step. Each 'build identity' contains a "Manifest" dictionary. It's entries look like
<?xml version="1.0" encoding="UTF-8"?>
 
  +
<key>BatteryCharging0</key>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "<nowiki>http://www.apple.com/DTDs/PropertyList-1.0.dtd</nowiki>">
 
 
<plist version="1.0">
 
 
<dict>
 
<dict>
<key>@APTicket</key>
+
<key>Digest</key>
  +
<nowiki><data>...</data></nowiki>
  +
<key>Info</key>
  +
<dict>...</dict>
  +
<key>Trusted<key/>
 
<true/>
 
<true/>
  +
<dict/>
<key>@HostIpAddress</key>
 
  +
They are just copied to the SHSH request, but the "Info" dictionary is removed.
<string>192.168.0.1</string>
 
  +
Example of a SHSH request (... values are identical, *** values are different per device):
<key>@HostPlatformInfo</key>
 
  +
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<string>windows</string> -------> "darwin" without quotes for Mac/Linux Systems
 
  +
<plist version="1.0">
<key>@Locality</key>
 
  +
<dict>
<string>en_US</string>
 
<key>@VersionInfo</key>
+
<key>@[[APTicket]]</key>
  +
<true />
<string>libauthinstall-34</string> -------> "3.8" without quotes for Mac/Linux Systems
 
  +
<true />
<integer>____</integer>
 
<key>ApChipID</key>
+
<key>@HostPlatformInfo</key>
<integer>____</integer>
+
<string>mac</string>
<key>ApECID</key>
+
<key>@Locality</key>
<string>*************</string> ------------> This is your own [[ECID]]
+
<string>en_US</string>
<key>ApProductionMode</key>
+
<key>@UUID</key>
  +
<string>D9C1F33D-62E0-4D25-8068-F5F46FE80057</string>
<true />
 
  +
<string>libauthinstall-391.0.0.1.3</string>
<integer>____</integer>
 
  +
<integer>10</integer>
<data>_________________________</data>
 
  +
<integer>35152</integer>
<data>****</data> -------> Here goes the nonce.
 
  +
<integer>***</integer>
<dict>
 
<data>_________________________</data>
+
<nowiki><data>***</data> </nowiki>
<key>PartialDigest</key>
+
<key>ApProductionMode</key>
  +
<true />
<data>_________________________</data>
 
<key>ApBoardID</key>
+
<key>@[[BBTicket]]</key>
<key>ApSecurityDomain</key>
+
<key>@VersionInfo</key>
<key>UniqueBuildID</key>
+
<key>[[BORD |ApBoardID]]</key>
<key>ApNonce</key>
+
<key>[[CHIP |ApChipID]]</key>
<key>AppleLogo</key>
+
<key>[[ECID |ApECID]]</key>
<key>Digest</key>
+
<key>[[Nonce |ApNonce]]</key>
<key>Trusted</key>
+
<key>ApSecurityDomain</key>
<true />
+
<integer>1</integer>
  +
<key>UniqueBuildID</key>
  +
<data> fqzW0B++Zdrs+PRwohkwU6prjbk=</data>
  +
<key>AppleLogo</key>
  +
<dict>
  +
<key>Digest</key>
  +
<nowiki><data> uH5QQax5YmIrgcuEHwOhAB//yc8=</data> </nowiki>
  +
<key>Trusted</key>
  +
<true />
 
</dict>
 
</dict>
<key>BatteryCharging</key>
+
<key>BatteryCharging0</key>
<dict>
+
<dict>
  +
... See AppleLogo dictionary.
<key>Digest</key>
 
  +
</dict>
<data>_________________________</data>
 
  +
<dict>
<data>_________________________</data>
 
  +
...
<key>Trusted</key>
 
  +
<key>BatteryFull</key>
</dict>
 
  +
<dict>
<key>BatteryCharging0</key>
 
<dict>
+
...
<key>Digest</key>
+
</dict>
  +
<key>BatteryLow0</key>
<data>_________________________</data>
 
  +
<dict>
<key>PartialDigest</key>
 
  +
...
<data>_________________________</data>
 
  +
<key>BatteryLow1</key>
<true />
 
  +
...
<key>BatteryCharging1</key>
 
<dict>
+
</dict>
<key>Digest</key>
+
<key>BatteryPlugin</key>
  +
<dict>
<data>_________________________</data>
 
  +
...
<key>PartialDigest</key>
 
  +
</dict>
<data>_________________________</data>
 
</dict>
+
...
  +
</dict>
<key>BatteryFull</key>
 
  +
<key>KernelCache</key>
<dict>
 
  +
<dict>
<key>Digest</key>
 
  +
...
<data>_________________________</data>
 
  +
</dict>
<key>PartialDigest</key>
 
  +
<key>LLB</key>
<data>_________________________</data>
 
  +
<dict>
<key>Trusted</key>
 
  +
<string>iBoot-2817.0.0.1.2~2</string>
</dict>
 
<key>BatteryLow0</key>
+
<key>PartialDigest</key>
  +
<nowiki><data> QAAAAHhRAgC22ZPWJB9J1Nh3H+0XeyRTU72ObA==</data> </nowiki>
<dict>
 
  +
...
<key>Digest</key>
 
  +
</dict>
<data>_________________________</data>
 
  +
<dict>
<data>_________________________</data>
 
  +
...
<key>Trusted</key>
 
<true />
+
</dict>
  +
<key>RestoreDeviceTree</key>
</dict>
 
  +
<dict>
<key>BatteryLow1</key>
 
<key>Digest</key>
+
</dict>
  +
<key>RestoreKernelCache</key>
<data>_________________________</data>
 
  +
<dict>
<key>PartialDigest</key>
 
  +
...
<data>_________________________</data>
 
  +
<key>RestoreLogo</key>
<true />
 
</dict>
+
<dict>
  +
...
<key>BatteryPlugin</key>
 
<key>Digest</key>
+
<key>RestoreRamDisk</key>
  +
<dict>
<data>_________________________</data>
 
  +
...
<key>PartialDigest</key>
 
  +
</dict>
<data>_________________________</data>
 
<true />
+
<dict>
  +
<key>BuildString</key>
</dict>
 
  +
<string>iBoot-2817.0.0.1.2~2</string>
<key>DeviceTree</key>
 
<key>Digest</key>
+
</dict>
  +
<key>[[iBSS]]</key>
<data>_________________________</data>
 
  +
<dict>
<key>PartialDigest</key>
 
  +
<key>BuildString</key>
<data>_________________________</data>
 
  +
<string>iBoot-2817.0.0.1.2~2</string>
<key>Trusted</key>
 
  +
<nowiki><data> QAAAAHhBAQCRc2PuoresMjW7zNLePMPmX7zaHg==</data> </nowiki>
</dict>
 
  +
...
<key>KernelCache</key>
 
<dict>
+
</dict>
<key>Digest</key>
+
<key>[[iBoot]]</key>
  +
<dict>
<data>_________________________</data>
 
  +
...
<key>PartialDigest</key>
 
  +
</dict>
<data>_________________________</data>
 
  +
</dict>
<key>Trusted</key>
 
<key>PartialDigest</key>
+
<key>BatteryCharging1</key>
<true />
+
</dict>
<key>Trusted</key>
+
</dict>
</dict>
+
<dict>
<key>Trusted</key>
+
<key>DeviceTree</key>
<true />
+
<dict>
<true />
+
<key>BuildString</key>
<key>PartialDigest</key>
+
<key>RecoveryMode</key>
<dict>
+
...
<key>Trusted</key>
+
</dict>
<dict>
+
</dict>
<key>Trusted</key>
+
<key>[[iBEC]]</key>
<dict>
+
...
<true />
+
<key>PartialDigest</key>
<true />
 
</dict>
 
<key>LLB</key>
 
<dict>
 
<key>BuildString</key>
 
<string>_________________________</string>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>RecoveryMode</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>RestoreDeviceTree</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>RestoreKernelCache</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>RestoreLogo</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>RestoreRamDisk</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>iBEC</key>
 
<dict>
 
<key>BuildString</key>
 
<string>_________________________</string>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>iBSS</key>
 
<dict>
 
<key>BuildString</key>
 
<string>_________________________</string>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
<key>iBoot</key>
 
<dict>
 
<key>Digest</key>
 
<data>_________________________</data>
 
<key>PartialDigest</key>
 
<data>_________________________</data>
 
<key>Trusted</key>
 
<true />
 
</dict>
 
</dict>
 
 
</plist>
 
</plist>
   
  +
===Receiving data (answer)===
The underlined values( _______ ) can be found from the BuildManifest.plist which is located inside a IPSW file.
 
  +
The response is a simple HTTP POST response, containing 3 values: STATUS, MESSAGE (a description string) and REQUEST_STRING (only if the request was successful). STATUS contains numeric status, MESSAGE contains an error message on error and "SUCCESS" string on success and REQUEST_STRING contains response property list encoded as XML.
   
 
===Status responses===
 
===Status responses===

Revision as of 12:50, 13 June 2015

Here is a description about the protocol that is used when iTunes requests the SHSH certificate from Apple. For details about what this is used for, please see the main article SHSH.

This is a simple HTTP (POST) request and answer. You can retry this via a Telnet session or similar. The destination host is gs.apple.com (IP 17.171.36.30 [previously 17.112.176.11]) and runs on the common port 80. The data is plaintext and not encoded in any way. For details about the HTTP protocol itself, please see RFC2616.

Sending data (request)

The request is actually a single XML encoded poperty list. It contains a dictionary which describes the target iOS version, restore behavior etc. Some of the required information can be taken from the BuildManifest.plist. BuildManifest contains some info about the firmware version and "BuildIdentities" dictionary. Inside it you can find two (or more?) build identities. Each of them contains the information which depends on every type of restore ("Erase" or "Update"). Some information is device-dependent (ECID, nonce) and is received from the device.

Request property list should have these properties:

  • @APTicket: Optional boolean value. If true, the server adds an APTicket to the request.
  • @BBTicket: The same for the BBTicket.
  • @UDID: Optional string value. Just request UDID. (ex. D9C1F33D-62E0-4D25-8068-F5F46FE80057).
  • @HostPlatformInfo: Optional(?) string value. "mac" for OS X client, "windows" for windows client (can be everything you want).
  • @Locality: Optional(?) string value. Language used for the error response (ex. "en_US");
  • @VersionInfo: Optional(?) string value. The version of 'libauthinstall' used (ex. "libauthinstall-391.0.0.1.3"). You can pass any string here.
  • ApBoardID: Integer value. Board ID of the target device. You can take this value from build manifest.
  • ApChipID: Integer value. Chip ID of the target device. You can take this value from build manifest.
  • ApECID: Integer value. ECID of the target device.
  • ApNonce: Data value. The nonce generated by your device.
  • ApProductionMode: Boolean value. Always true.
  • ApSecurityDomain: Integer value. The use is unknown. You can take this value from build manifest.
  • UniqueBuildID: Data value. This is a unique identifier for every build (different even for "Erase" and "Update" types of restore). You can take this value from build manifest.

The SHSH request also contains information about files from the IPSW (or restore bundle for PurpleRestore). They can be obtained from the 'build identity' you've chosen in the previous step. Each 'build identity' contains a "Manifest" dictionary. It's entries look like

<key>BatteryCharging0</key>
<dict>
	<key>Digest</key>
 	<data>...</data>
	<key>Info</key>
	<dict>...</dict>
 	<key>Trusted<key/>
	<true/>
<dict/>

They are just copied to the SHSH request, but the "Info" dictionary is removed. Example of a SHSH request (... values are identical, *** values are different per device):

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> 
<dict> 
	<key>@APTicket</key> 
	<true /> 
	<key>@BBTicket</key> 
	<true /> 
	<key>@HostPlatformInfo</key> 
	<string>mac</string> 
	<key>@Locality</key> 
	<string>en_US</string> 
	<key>@UUID</key> 
	<string>D9C1F33D-62E0-4D25-8068-F5F46FE80057</string> 
	<key>@VersionInfo</key> 
	<string>libauthinstall-391.0.0.1.3</string> 
	<key>ApBoardID</key> 
	<integer>10</integer>
	<key>ApChipID</key> 
	<integer>35152</integer> 
	<key>ApECID</key> 
	<integer>***</integer> 
	<key>ApNonce</key> 
	<data>***</data> 
	<key>ApProductionMode</key> 
	<true /> 
	<key>ApSecurityDomain</key> 
	<integer>1</integer> 
	<key>UniqueBuildID</key> 
	 fqzW0B++Zdrs+PRwohkwU6prjbk= 
	<key>AppleLogo</key> 
	<dict> 
		<key>Digest</key> 
		<data> uH5QQax5YmIrgcuEHwOhAB//yc8=</data> 
		<key>Trusted</key> 
		<true /> 
	</dict>
	<key>BatteryCharging0</key> 
	<dict> 
		... See AppleLogo dictionary.
	</dict> 
	<key>BatteryCharging1</key> 
	<dict> 
		...
	</dict> 
	<key>BatteryFull</key> 
	<dict> 
		... 
	</dict> 
	<key>BatteryLow0</key> 
	<dict> 
		...
	</dict> 
	<key>BatteryLow1</key> 
	<dict> 
		...
	</dict> 
	<key>BatteryPlugin</key> 
	<dict> 
		...
	</dict> 
	<key>DeviceTree</key> 
	<dict> 
		...
	</dict> 
	<key>KernelCache</key> 
	<dict> 
		...
	</dict> 
	<key>LLB</key> 
	<dict> 
		<key>BuildString</key> 
		<string>iBoot-2817.0.0.1.2~2</string> 
		<key>PartialDigest</key> 
		<data> QAAAAHhRAgC22ZPWJB9J1Nh3H+0XeyRTU72ObA==</data> 
		...
	</dict> 
	<key>RecoveryMode</key> 
	<dict> 
		...
	</dict> 
	<key>RestoreDeviceTree</key> 
	<dict> 
		...
	</dict> 
	<key>RestoreKernelCache</key> 
	<dict> 
		...
	</dict> 
	<key>RestoreLogo</key> 
	<dict> 
		... 
	</dict> 
	<key>RestoreRamDisk</key> 
	<dict> 
		...
	</dict> 
	<key>iBEC</key> 
	<dict> 
		<key>BuildString</key> 
		<string>iBoot-2817.0.0.1.2~2</string> 
		...
	</dict> 
	<key>iBSS</key> 
	<dict> 
		<key>BuildString</key> 
		<string>iBoot-2817.0.0.1.2~2</string> 
		<key>PartialDigest</key> 
		<data> QAAAAHhBAQCRc2PuoresMjW7zNLePMPmX7zaHg==</data> 
		...
	</dict> 
	<key>iBoot</key> 
	<dict> 
		...
	</dict> 
</dict> 
</plist>

Receiving data (answer)

The response is a simple HTTP POST response, containing 3 values: STATUS, MESSAGE (a description string) and REQUEST_STRING (only if the request was successful). STATUS contains numeric status, MESSAGE contains an error message on error and "SUCCESS" string on success and REQUEST_STRING contains response property list encoded as XML.

Status responses

  • STATUS=0&MESSAGE=SUCCESS
  • STATUS=94&MESSAGE=This device isn't eligible for the requested build.
  • STATUS=100&MESSAGE=An internal error occurred.
  • STATUS=511&MESSAGE=No data in the request
  • STATUS=551&MESSAGE=Error occured while importing config packet with cpsn:
  • STATUS=5000&MESSAGE=Invalid Option!

Other parameters / open questions

Some parameters could have other values. Not all details are known.

  • action=2 in the request. What other values exist and what is their meaning?
  • ApProductionMode What does this mean? Is there a test environment?
  • ApSecurityDomain Meaning?
  • Trusted What is this for?
  • Full description of the above values for UniqueBuildID, Digest, PartialDigest and BuildString.