1+ <?php
2+
3+ include_once dirname (__FILE__ ) . '/CasperAgent.php ' ;
4+ include_once dirname (__FILE__ ) . '/CasperException.php ' ;
5+
6+ /**
7+ * @file
8+ * PHP implementation of the Casper API.
9+ */
10+ class CasperAPI extends CasperAgent {
11+
12+ const SNAPCHAT_VERSION = "9.16.2.0 " ;
13+
14+ public function __construct ($ api_key = null , $ api_secret = null ){
15+ parent ::setAPIKey ($ api_key );
16+ parent ::setAPISecret ($ api_secret );
17+ }
18+
19+ public function getSnapchatInfo (){
20+ return parent ::get ("/snapchat " );
21+ }
22+
23+ /**
24+ * Fetches a Snapchat Client Auth Signature (X-Snapchat-Client-Auth) from the Casper API
25+ *
26+ * @param string $username
27+ * Your Snapchat Username
28+ *
29+ * @param string $password
30+ * Your Snapchat Password
31+ *
32+ * @param string $timestamp
33+ * The timestamp you send in the Snapchat Login Request
34+ *
35+ * @return string
36+ * The Client Auth Token
37+ *
38+ * @throws CasperException
39+ * An exception is thrown if an error occurs.
40+ */
41+ public function getSnapchatClientAuth ($ username , $ password , $ timestamp ){
42+
43+ $ response = parent ::post ("/snapchat/clientauth/signrequest " , null , array (
44+ "username " => $ username ,
45+ "password " => $ password ,
46+ "timestamp " => $ timestamp ,
47+ "snapchat_version " => self ::SNAPCHAT_VERSION
48+ ));
49+
50+ if (!isset ($ response ->signature )){
51+ throw new CasperException ("Signature not found in Response " );
52+ }
53+
54+ return $ response ->signature ;
55+
56+ }
57+
58+ /**
59+ * Fetches an Attestation by making multiple API calls to the Google and Casper APIs.
60+ *
61+ * @param string $nonce
62+ * Base64 encoded value of the nonce
63+ * sha256(username|password|timestamp|/loq/login)
64+ *
65+ * @return string
66+ * The Client Auth Token
67+ *
68+ * @throws CasperException
69+ * An exception is thrown if an error occurs.
70+ */
71+ public function getSnapchatAttestation ($ nonce ){
72+
73+ $ response = parent ::get ("/snapchat/attestation/create " );
74+
75+ if (!isset ($ response ->binary )){
76+ throw new CasperException ("Binary not found in Response " );
77+ }
78+
79+ $ binary = base64_decode ($ response ->binary );
80+
81+ $ response = parent ::externalRequest ("https://www.googleapis.com/androidantiabuse/v1/x/create?alt=PROTO&key=AIzaSyBofcZsgLSS7BOnBjZPEkk4rYwzOIz-lTI " , array (
82+ "Content-Type: application/x-protobuf " ,
83+ "User-Agent: SafetyNet/7899000 (klte KOT49H); gzip "
84+ ), $ binary , true );
85+
86+ $ protobuf = base64_encode ($ response );
87+
88+ $ response = parent ::post ("/snapchat/attestation/attest " , null , array (
89+ "protobuf " => $ protobuf ,
90+ "nonce " => $ nonce ,
91+ "snapchat_version " => self ::SNAPCHAT_VERSION
92+ ));
93+
94+ if (!isset ($ response ->binary )){
95+ throw new CasperException ("Binary not found in Response " );
96+ }
97+
98+ $ binary = base64_decode ($ response ->binary );
99+
100+ $ response = parent ::externalRequest ("https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=JSON&key=AIzaSyDqVnJBjE5ymo--oBJt3On7HQx9xNm1RHA " , array (
101+ "Content-Type: application/x-protobuf " ,
102+ "User-Agent: SafetyNet/7899000 (klte KOT49H); gzip "
103+ ), $ binary , true );
104+
105+ $ json = json_decode ($ response );
106+ if ($ json == null ){
107+ throw new CasperException ("Failed to decode response! " );
108+ }
109+
110+ if (!isset ($ json ->signedAttestation )){
111+ throw new CasperException ("Attestation not found in Response " );
112+ }
113+
114+ return $ json ->signedAttestation ;
115+
116+ }
117+
118+ /**
119+ * Generates an Nonce for Attestation requests.
120+ *
121+ * @param string $username
122+ * Snapchat Username
123+ *
124+ * @param string $password
125+ * Snapchat Password
126+ *
127+ * @param string $timestamp
128+ * Snapchat Login Timestamp
129+ *
130+ * @param string $endpoint
131+ * Snapchat Login Endpoint, always /loq/login at this stage.
132+ *
133+ * @return string
134+ * The Base64 Encoded Nonce
135+ *
136+ * @throws CasperException
137+ * An exception is thrown if an error occurs.
138+ */
139+ public function generateSnapchatNonce ($ username , $ password , $ timestamp , $ endpoint = "/loq/login " ){
140+ return base64_encode (hash ("sha256 " , "{$ username }| {$ password }| {$ timestamp }| {$ endpoint }" , true ));
141+ }
142+
143+ }
0 commit comments