mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 18:57:07 -07:00
LaunchSpec
This commit is contained in:
parent
02f3886d72
commit
f86ecd931b
11 changed files with 359 additions and 9 deletions
|
@ -11,7 +11,10 @@ set(HEADER_FILES
|
|||
include/chiaki/takion.h
|
||||
include/chiaki/senkusha.h
|
||||
include/chiaki/nagare.h
|
||||
include/chiaki/mirai.h)
|
||||
include/chiaki/mirai.h
|
||||
include/chiaki/ecdh.h
|
||||
include/chiaki/launchspec.h
|
||||
include/chiaki/random.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
src/common.c
|
||||
|
@ -27,7 +30,10 @@ set(SOURCE_FILES
|
|||
src/utils.h
|
||||
src/pb_utils.h
|
||||
src/nagare.c
|
||||
src/mirai.c)
|
||||
src/mirai.c
|
||||
src/ecdh.c
|
||||
src/launchspec.c
|
||||
src/random.c)
|
||||
|
||||
add_subdirectory(protobuf)
|
||||
include_directories("${NANOPB_SOURCE_DIR}")
|
||||
|
|
39
lib/include/chiaki/ecdh.h
Normal file
39
lib/include/chiaki/ecdh.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHIAKI_ECDH_H
|
||||
#define CHIAKI_ECDH_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct chiaki_ecdh_t
|
||||
{
|
||||
|
||||
} ChiakiECDH;
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh);
|
||||
CHIAKI_EXPORT void chiaki_ecdh_fini(ChiakiECDH *ecdh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CHIAKI_ECDH_H
|
43
lib/include/chiaki/launchspec.h
Normal file
43
lib/include/chiaki/launchspec.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHIAKI_LAUNCHSPEC_H
|
||||
#define CHIAKI_LAUNCHSPEC_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct chiaki_launch_spec_t
|
||||
{
|
||||
unsigned int mtu;
|
||||
unsigned int rtt;
|
||||
uint8_t *handshake_key;
|
||||
} ChiakiLaunchSpec;
|
||||
|
||||
CHIAKI_EXPORT ssize_t chiaki_launchspec_format(char *buf, size_t buf_size, ChiakiLaunchSpec *launch_spec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CHIAKI_LAUNCHSPEC_H
|
36
lib/include/chiaki/random.h
Normal file
36
lib/include/chiaki/random.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHIAKI_RANDOM_H
|
||||
#define CHIAKI_RANDOM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_random_bytes(uint8_t *buf, size_t buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CHIAKI_RANDOM_H
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
|
||||
#define CHIAKI_RP_DID_SIZE 32
|
||||
#define CHIAKI_SESSION_ID_SIZE_MAX 80
|
||||
#define CHIAKI_HANDSHAKE_KEY_SIZE 0x10
|
||||
|
||||
typedef struct chiaki_connect_info_t
|
||||
{
|
||||
|
@ -96,7 +97,10 @@ typedef struct chiaki_session_t
|
|||
|
||||
uint8_t nonce[CHIAKI_KEY_BYTES];
|
||||
ChiakiRPCrypt rpcrypt;
|
||||
char session_id[CHIAKI_SESSION_ID_SIZE_MAX];
|
||||
char session_id[CHIAKI_SESSION_ID_SIZE_MAX]; // zero-terminated
|
||||
uint8_t handshake_key[CHIAKI_HANDSHAKE_KEY_SIZE];
|
||||
unsigned int mtu;
|
||||
unsigned int rtt;
|
||||
|
||||
ChiakiQuitReason quit_reason;
|
||||
|
||||
|
|
28
lib/src/ecdh.c
Normal file
28
lib/src/ecdh.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chiaki/ecdh.h>
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh)
|
||||
{
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_ecdh_fini(ChiakiECDH *ecdh)
|
||||
{
|
||||
|
||||
}
|
90
lib/src/launchspec.c
Normal file
90
lib/src/launchspec.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chiaki/launchspec.h>
|
||||
#include <chiaki/session.h>
|
||||
#include <chiaki/base64.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char launchspec_fmt[] =
|
||||
"{"
|
||||
"\"sessionId\":\"sessionId4321\","
|
||||
"\"streamResolutions\":["
|
||||
"{"
|
||||
"\"resolution\":"
|
||||
"{"
|
||||
"\"width\":640,"
|
||||
"\"height\":360"
|
||||
"},"
|
||||
"\"maxFps\":30,"
|
||||
"\"score\":10"
|
||||
"}"
|
||||
"],"
|
||||
"\"network\":{"
|
||||
"\"bwKbpsSent\":2000,"
|
||||
"\"bwLoss\":0.001000,"
|
||||
"\"mtu\":%u," // 0
|
||||
"\"rtt\":%u," // 1
|
||||
"\"ports\":[53,2053]"
|
||||
"},"
|
||||
"\"slotId\":1,"
|
||||
"\"appSpecification\":{"
|
||||
"\"minFps\":30,"
|
||||
"\"minBandwidth\":0,"
|
||||
"\"extTitleId\":\"ps3\","
|
||||
"\"version\":1,"
|
||||
"\"timeLimit\":1,"
|
||||
"\"startTimeout\":100,"
|
||||
"\"afkTimeout\":100,"
|
||||
"\"afkTimeoutDisconnect\":100"
|
||||
"},"
|
||||
"\"konan\":{"
|
||||
"\"ps3AccessToken\":\"accessToken\","
|
||||
"\"ps3RefreshToken\":\"refreshToken\""
|
||||
"},\"requestGameSpecification\":{"
|
||||
"\"model\":\"bravia_tv\","
|
||||
"\"platform\":\"android\","
|
||||
"\"audioChannels\":\"5.1\","
|
||||
"\"language\":\"sp\","
|
||||
"\"acceptButton\":\"X\","
|
||||
"\"connectedControllers\":[\"xinput\",\"ds3\",\"ds4\"],"
|
||||
"\"yuvCoefficient\":\"bt601\","
|
||||
"\"videoEncoderProfile\":\"hw4.1\","
|
||||
"\"audioEncoderProfile\":\"audio1\""
|
||||
"},"
|
||||
"\"userProfile\":{"
|
||||
"\"onlineId\":\"psnId\","
|
||||
"\"npId\":\"npId\","
|
||||
"\"region\":\"US\","
|
||||
"\"languagesUsed\":[\"en\",\"jp\"]"
|
||||
"},"
|
||||
"\"handshakeKey\":\"%s\"" // 2
|
||||
"}";
|
||||
|
||||
CHIAKI_EXPORT ssize_t chiaki_launchspec_format(char *buf, size_t buf_size, ChiakiLaunchSpec *launch_spec)
|
||||
{
|
||||
char handshake_key_b64[CHIAKI_HANDSHAKE_KEY_SIZE * 2];
|
||||
ChiakiErrorCode err = chiaki_base64_encode(launch_spec->handshake_key, CHIAKI_HANDSHAKE_KEY_SIZE, handshake_key_b64, sizeof(handshake_key_b64));
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return -1;
|
||||
|
||||
int written = snprintf(buf, buf_size, launchspec_fmt, launch_spec->mtu, launch_spec->rtt, handshake_key_b64);
|
||||
if(written < 0 || written >= buf_size)
|
||||
return -1;
|
||||
return written;
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <chiaki/nagare.h>
|
||||
#include <chiaki/session.h>
|
||||
#include <chiaki/launchspec.h>
|
||||
#include <chiaki/base64.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -43,6 +45,7 @@ static ChiakiErrorCode nagare_send_disconnect(ChiakiNagare *nagare);
|
|||
CHIAKI_EXPORT ChiakiErrorCode chiaki_nagare_run(ChiakiSession *session)
|
||||
{
|
||||
ChiakiNagare *nagare = &session->nagare;
|
||||
nagare->session = session;
|
||||
nagare->log = &session->log;
|
||||
|
||||
ChiakiErrorCode err = chiaki_mirai_init(&nagare->bang_mirai);
|
||||
|
@ -144,20 +147,71 @@ static void nagare_takion_data(uint8_t *buf, size_t buf_size, void *user)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static bool chiaki_pb_encode_zero_encrypted_key(pb_ostream_t *stream, const pb_field_t *field, void *const *arg)
|
||||
{
|
||||
if (!pb_encode_tag_for_field(stream, field))
|
||||
return false;
|
||||
uint8_t data[] = { 0, 0, 0, 0 };
|
||||
return pb_encode_string(stream, data, sizeof(data));
|
||||
}
|
||||
|
||||
#define LAUNCH_SPEC_JSON_BUF_SIZE 1024
|
||||
|
||||
static ChiakiErrorCode nagare_send_big(ChiakiNagare *nagare)
|
||||
{
|
||||
ChiakiSession *session = nagare->session;
|
||||
|
||||
ChiakiLaunchSpec launch_spec;
|
||||
launch_spec.mtu = session->mtu;
|
||||
launch_spec.rtt = session->rtt;
|
||||
launch_spec.handshake_key = session->handshake_key;
|
||||
|
||||
union
|
||||
{
|
||||
char json[LAUNCH_SPEC_JSON_BUF_SIZE];
|
||||
char b64[LAUNCH_SPEC_JSON_BUF_SIZE * 2];
|
||||
} launch_spec_buf;
|
||||
ssize_t launch_spec_json_size = chiaki_launchspec_format(launch_spec_buf.json, sizeof(launch_spec_buf.json), &launch_spec);
|
||||
if(launch_spec_json_size != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(nagare->log, "Nagare failed to format LaunchSpec json\n");
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
launch_spec_json_size += 1; // we also want the trailing 0
|
||||
|
||||
uint8_t launch_spec_json_enc[LAUNCH_SPEC_JSON_BUF_SIZE];
|
||||
memset(launch_spec_json_enc, 0, (size_t)launch_spec_json_size);
|
||||
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 0, launch_spec_json_enc, launch_spec_json_enc,
|
||||
(size_t)launch_spec_json_size);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(nagare->log, "Nagare failed to encrypt LaunchSpec\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
xor_bytes(launch_spec_json_enc, (uint8_t *)launch_spec_buf.json, (size_t)launch_spec_json_size);
|
||||
err = chiaki_base64_encode(launch_spec_json_enc, (size_t)launch_spec_json_size, launch_spec_buf.b64, sizeof(launch_spec_buf.b64));
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(nagare->log, "Nagare failed to encode LaunchSpec as base64\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
tkproto_TakionMessage msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
msg.type = tkproto_TakionMessage_PayloadType_BIG;
|
||||
msg.has_big_payload = true;
|
||||
msg.big_payload.client_version = 9;
|
||||
msg.big_payload.session_key.arg = "";
|
||||
msg.big_payload.session_key.arg = session->session_id;
|
||||
msg.big_payload.session_key.funcs.encode = chiaki_pb_encode_string;
|
||||
msg.big_payload.launch_spec.arg = "";
|
||||
msg.big_payload.launch_spec.arg = launch_spec_buf.b64;
|
||||
msg.big_payload.launch_spec.funcs.encode = chiaki_pb_encode_string;
|
||||
msg.big_payload.encrypted_key.arg = "";
|
||||
msg.big_payload.encrypted_key.funcs.encode = chiaki_pb_encode_string;
|
||||
msg.big_payload.encrypted_key.funcs.encode = chiaki_pb_encode_zero_encrypted_key;
|
||||
|
||||
// TODO: msg.big_payload.ecdh_pub_key
|
||||
// TODO: msg.big_payload.ecdh_sig
|
||||
|
||||
uint8_t buf[12];
|
||||
size_t buf_size;
|
||||
|
@ -171,7 +225,7 @@ static ChiakiErrorCode nagare_send_big(ChiakiNagare *nagare)
|
|||
}
|
||||
|
||||
buf_size = stream.bytes_written;
|
||||
ChiakiErrorCode err = chiaki_takion_send_message_data(&nagare->takion, 0, 1, 1, buf, buf_size);
|
||||
err = chiaki_takion_send_message_data(&nagare->takion, 0, 1, 1, buf, buf_size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
28
lib/src/random.c
Normal file
28
lib/src/random.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chiaki/random.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_random_bytes(uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
int r = RAND_bytes(buf, (int)buf_size);
|
||||
if(!r)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
#include <chiaki/session.h>
|
||||
#include <chiaki/http.h>
|
||||
#include <chiaki/base64.h>
|
||||
#include <chiaki/random.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -163,8 +164,19 @@ static void *session_thread_func(void *arg)
|
|||
goto quit_ctrl;
|
||||
}
|
||||
|
||||
// TODO: Senkusha should set that
|
||||
session->mtu = 1454;
|
||||
session->rtt = 12;
|
||||
|
||||
CHIAKI_LOGI(&session->log, "Senkusha completed successfully\n");
|
||||
|
||||
err = chiaki_random_bytes(session->handshake_key, sizeof(session->handshake_key));
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(&session->log, "Session failed to generate handshake key\n");
|
||||
goto quit_ctrl;
|
||||
}
|
||||
|
||||
err = chiaki_nagare_run(session);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
|
@ -375,4 +387,3 @@ static bool session_thread_request_session(ChiakiSession *session)
|
|||
close(session_sock);
|
||||
return response.success;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,4 +32,15 @@ static inline ChiakiErrorCode set_port(struct sockaddr *sa, in_port_t port)
|
|||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void xor_bytes(uint8_t *dst, uint8_t *src, size_t sz)
|
||||
{
|
||||
while(sz > 0)
|
||||
{
|
||||
*dst ^= *src;
|
||||
dst++;
|
||||
src++;
|
||||
sz--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHIAKI_UTILS_H
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue