// HTTPS mit der MBMNET-CA, siehe https.h #include <3ds.h> #include #include #include "https.h" #include "olvpatch.h" static u8 caDer[1024]; static u32 caLen; static LightLock caLock = 1; // 1 = entsperrt (LightLock_Init) u32 https_request(const char *server, const char *path, const char *form, const char *header, const char *value, char *out, u32 cap, u32 *outLen, char *date, size_t dateLen, Result *rcOut) { static u32 formBuf[64]; Result rc = 0; *outLen = 0; if (cap) out[0] = 0; if (date && dateLen) date[0] = 0; LightLock_Lock(&caLock); bool haveCa = caLen || olvpatch_fetch_ca(server, caDer, &caLen); LightLock_Unlock(&caLock); if (!haveCa) { if (rcOut) *rcOut = -1; return 0; } char url[224]; snprintf(url, sizeof(url), "https://%s%s", server, path); httpcContext ctx; if (R_FAILED(rc = httpcOpenContext(&ctx, form ? HTTPC_METHOD_POST : HTTPC_METHOD_GET, url, 1))) { if (rcOut) *rcOut = rc; return 0; } httpcAddRequestHeaderField(&ctx, "User-Agent", "MBMNET-Switcher/" APP_VERSION); httpcSetKeepAlive(&ctx, HTTPC_KEEPALIVE_DISABLED); httpcAddTrustedRootCA(&ctx, caDer, caLen); // nur der MBMNET-CA vertrauen wir zusätzlich if (header && value) httpcAddRequestHeaderField(&ctx, header, value); if (form) { u32 n = strlen(form); if (n >= sizeof(formBuf)) n = sizeof(formBuf) - 1; memcpy(formBuf, form, n); httpcAddRequestHeaderField(&ctx, "Content-Type", "application/x-www-form-urlencoded"); httpcAddPostDataRaw(&ctx, formBuf, n); } u32 code = 0; rc = httpcBeginRequest(&ctx); if (R_SUCCEEDED(rc)) rc = httpcGetResponseStatusCodeTimeout(&ctx, &code, 10ULL * 1000 * 1000 * 1000); if (R_SUCCEEDED(rc)) { if (date && dateLen) httpcGetResponseHeader(&ctx, "Date", date, dateLen); u32 size = 0, got; do { got = 0; rc = httpcDownloadData(&ctx, (u8 *)out + size, cap - 1 - size, &got); size += got; } while (rc == (Result)HTTPC_RESULTCODE_DOWNLOADPENDING && size < cap - 1); out[size] = 0; *outLen = size; if (rc == (Result)HTTPC_RESULTCODE_DOWNLOADPENDING) rc = 0; // Puffer voll: abgeschnitten } httpcCloseContext(&ctx); memset(formBuf, 0, sizeof(formBuf)); // Passwort nicht im Speicher liegen lassen if (rcOut) *rcOut = rc; return code; }