65 lines
2.4 KiB
C
65 lines
2.4 KiB
C
// HTTPS mit der MBMNET-CA, siehe https.h
|
|
#include <3ds.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|