mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Refactor out some duplicated code
This commit is contained in:
parent
e963d9c8e3
commit
579b597ded
58 changed files with 1110 additions and 3214 deletions
1279
ape/etc/bochsrc.dbg
1279
ape/etc/bochsrc.dbg
File diff suppressed because it is too large
Load diff
1294
ape/etc/bochsrc.ffs
1294
ape/etc/bochsrc.ffs
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
|
@ -21,9 +21,11 @@
|
|||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
|
@ -63,32 +65,11 @@
|
|||
#define HeaderEqualCase(H, S) \
|
||||
SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H))
|
||||
|
||||
static inline bool SlicesEqualCase(const char *a, size_t n, const char *b,
|
||||
size_t m) {
|
||||
return n == m && !memcasecmp(a, b, n);
|
||||
}
|
||||
|
||||
static bool TuneSocket(int fd, int a, int b, int x) {
|
||||
if (!b) return false;
|
||||
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
|
||||
}
|
||||
|
||||
static int Socket(int family, int type, int protocol) {
|
||||
int fd;
|
||||
if ((fd = socket(family, type, protocol)) != -1) {
|
||||
TuneSocket(fd, SOL_SOCKET, SO_KEEPALIVE, 1);
|
||||
if (protocol == SOL_TCP) {
|
||||
TuneSocket(fd, SOL_TCP, TCP_KEEPIDLE, 60);
|
||||
TuneSocket(fd, SOL_TCP, TCP_KEEPINTVL, 60);
|
||||
TuneSocket(fd, SOL_TCP, TCP_FASTOPEN_CONNECT, 1);
|
||||
if (!TuneSocket(fd, SOL_TCP, TCP_QUICKACK, 1)) {
|
||||
TuneSocket(fd, SOL_TCP, TCP_NODELAY, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int TlsSend(void *c, const unsigned char *p, size_t n) {
|
||||
int rc;
|
||||
NOISEF("begin send %zu", n);
|
||||
|
@ -119,35 +100,11 @@ static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
|
|||
return MIN(n, r);
|
||||
}
|
||||
|
||||
static void TlsDebug(void *c, int v, const char *f, int l, const char *s) {
|
||||
flogf(v, f, l, 0, "TLS %s", s);
|
||||
}
|
||||
|
||||
static char *TlsError(int r) {
|
||||
static char b[128];
|
||||
mbedtls_strerror(r, b, sizeof(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
||||
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
static wontreturn void TlsDie(const char *s, int r) {
|
||||
if (IsTiny()) {
|
||||
fprintf(stderr, "error: %s (-0x%04x %s)\n", s, -r, TlsError(r));
|
||||
} else {
|
||||
fprintf(stderr, "error: %s (grep -0x%04x)\n", s, -r);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int GetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
CHECK_EQ(n, getrandom(p, n, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!NoDebug()) showcrashreports();
|
||||
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);
|
||||
|
@ -302,8 +259,9 @@ int main(int argc, char *argv[]) {
|
|||
* Connect to server.
|
||||
*/
|
||||
int ret, sock;
|
||||
CHECK_NE(-1, (sock = Socket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol)));
|
||||
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol, false,
|
||||
&(struct timeval){-60})));
|
||||
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
|
||||
freeaddrinfo(addr);
|
||||
if (usessl) {
|
||||
|
|
39
libc/calls/addrusage.c
Normal file
39
libc/calls/addrusage.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/math.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void AddRusage(struct rusage *x, const struct rusage *y) {
|
||||
AddTimeval(&x->ru_utime, &y->ru_utime);
|
||||
AddTimeval(&x->ru_stime, &y->ru_stime);
|
||||
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
|
||||
x->ru_ixrss += y->ru_ixrss;
|
||||
x->ru_idrss += y->ru_idrss;
|
||||
x->ru_isrss += y->ru_isrss;
|
||||
x->ru_minflt += y->ru_minflt;
|
||||
x->ru_majflt += y->ru_majflt;
|
||||
x->ru_nswap += y->ru_nswap;
|
||||
x->ru_inblock += y->ru_inblock;
|
||||
x->ru_oublock += y->ru_oublock;
|
||||
x->ru_msgsnd += y->ru_msgsnd;
|
||||
x->ru_msgrcv += y->ru_msgrcv;
|
||||
x->ru_nsignals += y->ru_nsignals;
|
||||
x->ru_nvcsw += y->ru_nvcsw;
|
||||
x->ru_nivcsw += y->ru_nivcsw;
|
||||
}
|
28
libc/calls/addtimeval.c
Normal file
28
libc/calls/addtimeval.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/math.h"
|
||||
|
||||
void AddTimeval(struct timeval *x, const struct timeval *y) {
|
||||
x->tv_sec += y->tv_sec;
|
||||
x->tv_usec += y->tv_usec;
|
||||
if (x->tv_usec >= 1000000) {
|
||||
x->tv_usec -= 1000000;
|
||||
x->tv_sec += 1;
|
||||
}
|
||||
}
|
13
libc/calls/math.h
Normal file
13
libc/calls/math.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void AddTimeval(struct timeval *, const struct timeval *);
|
||||
void AddRusage(struct rusage *, const struct rusage *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_MATH_H_ */
|
|
@ -39,6 +39,7 @@ long sizetol(const char *, long) paramsnonnull() libcesque;
|
|||
│ cosmopolitan § conversion » time ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
struct timespec WindowsTimeToTime(uint64_t);
|
||||
int64_t DosDateTimeToUnix(unsigned, unsigned);
|
||||
struct timespec FileTimeToTimeSpec(struct NtFileTime);
|
||||
struct NtFileTime TimeSpecToFileTime(struct timespec);
|
||||
|
@ -48,6 +49,11 @@ void FileTimeToTimeVal(struct timeval *, struct NtFileTime) nothrow;
|
|||
struct NtFileTime TimeValToFileTime(const struct timeval *) nosideeffect;
|
||||
long convertmicros(const struct timeval *, long) paramsnonnull() nosideeffect;
|
||||
|
||||
/* forceinline struct timespec WindowsTimeToTime(uint64_t x) { */
|
||||
/* return (struct timespec){x / HECTONANOSECONDS - MODERNITYSECONDS, */
|
||||
/* x % HECTONANOSECONDS * 100}; */
|
||||
/* } */
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § conversion » manipulation ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
|
|
@ -58,6 +58,7 @@ $(LIBC_FMT_A_OBJS): \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-fno-jump-tables
|
||||
|
||||
o/$(MODE)/libc/fmt/windowstimetotime.o \
|
||||
o/$(MODE)/libc/fmt/dosdatetimetounix.o \
|
||||
o/$(MODE)/libc/fmt/itoa64radix10.greg.o \
|
||||
o/$(MODE)/libc/fmt/timetofiletime.o \
|
||||
|
|
59
libc/sock/goodsocket.c
Normal file
59
libc/sock/goodsocket.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/consts/tcp.h"
|
||||
|
||||
static bool Tune(int fd, int a, int b, int x) {
|
||||
if (!b) return false;
|
||||
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new socket with modern goodness enabled.
|
||||
*/
|
||||
int GoodSocket(int family, int type, int protocol, bool isserver,
|
||||
const struct timeval *timeout) {
|
||||
int fd;
|
||||
if ((fd = socket(family, type, protocol)) != -1) {
|
||||
if (isserver) {
|
||||
Tune(fd, SOL_TCP, TCP_FASTOPEN, 100);
|
||||
Tune(fd, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
} else {
|
||||
Tune(fd, SOL_TCP, TCP_FASTOPEN_CONNECT, 1);
|
||||
}
|
||||
if (!Tune(fd, SOL_TCP, TCP_QUICKACK, 1)) {
|
||||
Tune(fd, SOL_TCP, TCP_NODELAY, 1);
|
||||
}
|
||||
if (timeout) {
|
||||
if (timeout->tv_sec < 0) {
|
||||
Tune(fd, SOL_SOCKET, SO_KEEPALIVE, 1);
|
||||
Tune(fd, SOL_TCP, TCP_KEEPIDLE, -timeout->tv_sec);
|
||||
Tune(fd, SOL_TCP, TCP_KEEPINTVL, -timeout->tv_sec);
|
||||
} else {
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, timeout, sizeof(*timeout));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, timeout, sizeof(*timeout));
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
11
libc/sock/goodsocket.internal.h
Normal file
11
libc/sock/goodsocket.internal.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_GOODSOCKET_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_GOODSOCKET_H_
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int GoodSocket(int, int, int, bool, const struct timeval *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_GOODSOCKET_H_ */
|
28
libc/str/compareslices.c
Normal file
28
libc/str/compareslices.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/slice.h"
|
||||
|
||||
int CompareSlices(const char *a, size_t n, const char *b, size_t m) {
|
||||
int c;
|
||||
if ((c = memcmp(a, b, MIN(n, m)))) return c;
|
||||
if (n < m) return -1;
|
||||
if (n > m) return +1;
|
||||
return 0;
|
||||
}
|
28
libc/str/compareslicescase.c
Normal file
28
libc/str/compareslicescase.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/slice.h"
|
||||
|
||||
int CompareSlicesCase(const char *a, size_t n, const char *b, size_t m) {
|
||||
int c;
|
||||
if ((c = memcasecmp(a, b, MIN(n, m)))) return c;
|
||||
if (n < m) return -1;
|
||||
if (n > m) return +1;
|
||||
return 0;
|
||||
}
|
101
libc/str/getzipcfiletimestamps.c
Normal file
101
libc/str/getzipcfiletimestamps.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/zip.h"
|
||||
|
||||
static inline int pop(int x) {
|
||||
return !!(x & 1) + !!(x & 2) + !!(x & 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts modified/access/creation timestamps from zip entry.
|
||||
*
|
||||
* @param cf is pointer to central directory header for file
|
||||
* @param mtim optionally receives last modified timestamp
|
||||
* @param atim optionally receives modified timestamp
|
||||
* @param ctim optionally receives creation timestamp
|
||||
* @param gmtoff is seconds adjustment for legacy dos timestamps
|
||||
*/
|
||||
void GetZipCfileTimestamps(const uint8_t *cf, struct timespec *mtim,
|
||||
struct timespec *atim, struct timespec *ctim,
|
||||
int gmtoff) {
|
||||
const uint8_t *p, *pe;
|
||||
if (mtim) *mtim = (struct timespec){0};
|
||||
if (atim) *atim = (struct timespec){0};
|
||||
if (ctim) *ctim = (struct timespec){0};
|
||||
for (p = ZIP_CFILE_EXTRA(cf), pe = p + ZIP_CFILE_EXTRASIZE(cf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraNtfs &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 4) == 1 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 8) {
|
||||
if (mtim) {
|
||||
*mtim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8));
|
||||
}
|
||||
if (atim && ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 2 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 16) {
|
||||
*atim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 2));
|
||||
}
|
||||
if (ctim && ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 3 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 24) {
|
||||
*ctim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(cf), pe = p + ZIP_CFILE_EXTRASIZE(cf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraExtendedTimestamp &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) > 1 &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) == 1 + 4 * pop(*ZIP_EXTRA_CONTENT(p) & 7)) {
|
||||
if (mtim) {
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 1) {
|
||||
mtim->tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 1);
|
||||
} else {
|
||||
mtim->tv_sec = DosDateTimeToUnix(ZIP_CFILE_LASTMODIFIEDDATE(cf),
|
||||
ZIP_CFILE_LASTMODIFIEDTIME(cf)) -
|
||||
gmtoff;
|
||||
}
|
||||
}
|
||||
if (atim && (*ZIP_EXTRA_CONTENT(p) & 2)) {
|
||||
atim->tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * (*ZIP_EXTRA_CONTENT(p) & 1));
|
||||
}
|
||||
if (ctim && (*ZIP_EXTRA_CONTENT(p) & 4)) {
|
||||
ctim->tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * pop(*ZIP_EXTRA_CONTENT(p) & 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(cf), pe = p + ZIP_CFILE_EXTRASIZE(cf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraUnix &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4) {
|
||||
if (atim) atim->tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 0);
|
||||
if (mtim) mtim->tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mtim) {
|
||||
mtim->tv_sec = DosDateTimeToUnix(ZIP_CFILE_LASTMODIFIEDDATE(cf),
|
||||
ZIP_CFILE_LASTMODIFIEDTIME(cf)) -
|
||||
gmtoff;
|
||||
}
|
||||
}
|
32
libc/str/istext.c
Normal file
32
libc/str/istext.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Returns true if buffer is most likely plaintext.
|
||||
*/
|
||||
bool IsText(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p < pe; ++p) {
|
||||
if (*p <= 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
38
libc/str/isutf8.c
Normal file
38
libc/str/isutf8.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Returns true if text data is most likely utf-8.
|
||||
*
|
||||
* This function will return false if a pure ascii string is passed.
|
||||
*/
|
||||
bool IsUtf8(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p + 2 <= pe; ++p) {
|
||||
if (p[0] >= 0300) {
|
||||
if (p[1] >= 0200 && p[1] < 0300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
22
libc/str/slice.h
Normal file
22
libc/str/slice.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_SLICE_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_SLICE_H_
|
||||
#include "libc/str/str.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
forceinline bool SlicesEqual(const char *a, size_t n, const char *b, size_t m) {
|
||||
return n == m && !memcmp(a, b, n);
|
||||
}
|
||||
|
||||
forceinline bool SlicesEqualCase(const void *a, size_t n, const void *b,
|
||||
size_t m) {
|
||||
return n == m && !memcasecmp(a, b, n);
|
||||
}
|
||||
|
||||
int CompareSlices(const char *, size_t, const char *, size_t);
|
||||
int CompareSlicesCase(const char *, size_t, const char *, size_t);
|
||||
bool StartsWithIgnoreCase(const char *, const char *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_SLICE_H_ */
|
27
libc/str/startswithi.c
Normal file
27
libc/str/startswithi.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
bool startswithi(const char *s, const char *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (kToLower[*s++ & 255] != (*prefix++ & 255)) return false;
|
||||
}
|
||||
}
|
|
@ -171,6 +171,7 @@ wchar_t *wcstok(wchar_t *, const wchar_t *, wchar_t **) paramsnonnull((2, 3));
|
|||
char *wstrtrunc(uint16_t *) memcpyesque;
|
||||
char *wstrntrunc(uint16_t *, size_t) memcpyesque;
|
||||
bool startswith(const char *, const char *) strlenesque;
|
||||
bool startswithi(const char *, const char *) strlenesque;
|
||||
bool startswith16(const char16_t *, const char16_t *) strlenesque;
|
||||
bool wcsstartswith(const wchar_t *, const wchar_t *) strlenesque;
|
||||
bool endswith(const char *, const char *) strlenesque;
|
||||
|
@ -197,6 +198,8 @@ char *strtoupper(char *) paramsnonnull();
|
|||
char *chomp(char *);
|
||||
char16_t *chomp16(char16_t *);
|
||||
wchar_t *wchomp(wchar_t *);
|
||||
bool IsText(const void *, size_t);
|
||||
bool IsUtf8(const void *, size_t);
|
||||
|
||||
bool escapedos(char16_t *, unsigned, const char16_t *, unsigned);
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@ o/$(MODE)/libc/str/memmem.o: \
|
|||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o//libc/str/bzero.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O2
|
||||
|
||||
o/$(MODE)/libc/str/dosdatetimetounix.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O3
|
||||
|
||||
o/$(MODE)/libc/str/getzipcdir.o \
|
||||
o/$(MODE)/libc/str/getzipcdircomment.o \
|
||||
o/$(MODE)/libc/str/getzipcdircommentsize.o \
|
||||
|
@ -58,20 +66,21 @@ o/$(MODE)/libc/str/getzipcfilemode.o \
|
|||
o/$(MODE)/libc/str/getzipcfileoffset.o \
|
||||
o/$(MODE)/libc/str/getzipcfileuncompressedsize.o \
|
||||
o/$(MODE)/libc/str/getziplfilecompressedsize.o \
|
||||
o/$(MODE)/libc/str/getziplfileuncompressedsize.o: \
|
||||
o/$(MODE)/libc/str/getziplfileuncompressedsize.o \
|
||||
o/$(MODE)/libc/str/getzipcfiletimestamps.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
o//libc/str/bzero.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O2
|
||||
|
||||
o/$(MODE)/libc/str/iswpunct.o \
|
||||
o/$(MODE)/libc/str/iswupper.o \
|
||||
o/$(MODE)/libc/str/iswlower.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-fno-jump-tables
|
||||
|
||||
o/$(MODE)/libc/str/windowstimetotime.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O3
|
||||
|
||||
LIBC_STR_LIBS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)))
|
||||
LIBC_STR_SRCS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_STR_HDRS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
24
libc/str/windowstimetotime.c
Normal file
24
libc/str/windowstimetotime.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
|
||||
struct timespec WindowsTimeToTime(uint64_t x) {
|
||||
return (struct timespec){x / HECTONANOSECONDS - MODERNITYSECONDS,
|
||||
x % HECTONANOSECONDS * 100};
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_ZIP_H_
|
||||
#define COSMOPOLITAN_LIBC_ZIP_H_
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
|
@ -199,6 +200,8 @@ uint64_t GetZipCfileOffset(const uint8_t *);
|
|||
uint64_t GetZipLfileUncompressedSize(const uint8_t *);
|
||||
uint64_t GetZipLfileCompressedSize(const uint8_t *);
|
||||
uint8_t *zipfindcentraldir(const uint8_t *, size_t);
|
||||
void GetZipCfileTimestamps(const uint8_t *, struct timespec *,
|
||||
struct timespec *, struct timespec *, int);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_ZIP_H_ */
|
||||
|
|
|
@ -18,75 +18,12 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
static int popcnt3(int x) {
|
||||
return !!(x & 1) + !!(x & 2) + !!(x & 4);
|
||||
}
|
||||
|
||||
static struct timespec WindowsTimeToTime(uint64_t x) {
|
||||
return (struct timespec){x / HECTONANOSECONDS - MODERNITYSECONDS,
|
||||
x % HECTONANOSECONDS * 100};
|
||||
}
|
||||
|
||||
static void GetZipCfileTimestamps(const uint8_t *zcf, struct stat *st) {
|
||||
const uint8_t *p, *pe;
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraNtfs &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 4) == 1 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 8) {
|
||||
st->st_mtim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8));
|
||||
if (ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 2 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 16) {
|
||||
st->st_atim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 2));
|
||||
}
|
||||
if (ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 3 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 24) {
|
||||
st->st_ctim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraExtendedTimestamp &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) > 1 &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) ==
|
||||
1 + 4 * popcnt3(*ZIP_EXTRA_CONTENT(p) & 7)) {
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 1) {
|
||||
st->st_mtim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1);
|
||||
}
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 2) {
|
||||
st->st_atim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * (*ZIP_EXTRA_CONTENT(p) & 1));
|
||||
}
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 4) {
|
||||
st->st_ctim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * popcnt3(*ZIP_EXTRA_CONTENT(p) & 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraUnix &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4) {
|
||||
st->st_atim.tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 0);
|
||||
st->st_mtim.tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
st->st_mtim.tv_sec = DosDateTimeToUnix(ZIP_CFILE_LASTMODIFIEDDATE(zcf),
|
||||
ZIP_CFILE_LASTMODIFIEDTIME(zcf));
|
||||
}
|
||||
|
||||
int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
|
||||
size_t lf;
|
||||
if (zipos && st) {
|
||||
|
@ -100,7 +37,8 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
|
|||
st->st_size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||
st->st_blocks =
|
||||
roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512;
|
||||
GetZipCfileTimestamps(zipos->map + cf, st);
|
||||
GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim,
|
||||
&st->st_ctim, 0);
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
|
|
32
net/https/certhashost.c
Normal file
32
net/https/certhashost.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/slice.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
bool CertHasHost(const mbedtls_x509_crt *cert, const void *s, size_t n) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
SlicesEqualCase(s, n, cur->buf.p, cur->buf.len)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
32
net/https/certhasip.c
Normal file
32
net/https/certhasip.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
bool CertHasIp(const mbedtls_x509_crt *cert, uint32_t ip) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_IP_ADDRESS &&
|
||||
cur->buf.len == 4 && ip == READ32BE(cur->buf.p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
35
net/https/chaincertificate.c
Normal file
35
net/https/chaincertificate.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
bool ChainCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *parent) {
|
||||
if (!mbedtls_x509_crt_check_signature(cert, parent, 0)) {
|
||||
DEBUGF("chaining %`'s to %`'s", gc(FormatX509Name(&cert->subject)),
|
||||
gc(FormatX509Name(&parent->subject)));
|
||||
cert->next = parent;
|
||||
return true;
|
||||
} else {
|
||||
WARNF("signature check failed for %`'s -> %`'s",
|
||||
gc(FormatX509Name(&cert->subject)),
|
||||
gc(FormatX509Name(&parent->subject)));
|
||||
return false;
|
||||
}
|
||||
}
|
33
net/https/choosecertificatelifetime.c
Normal file
33
net/https/choosecertificatelifetime.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
void ChooseCertificateLifetime(char notbefore[16], char notafter[16]) {
|
||||
struct tm tm;
|
||||
int64_t past, now, future, lifetime, tolerance;
|
||||
tolerance = 60 * 60 * 24;
|
||||
lifetime = 60 * 60 * 24 * 365;
|
||||
now = nowl();
|
||||
past = now - tolerance;
|
||||
future = now + tolerance + lifetime;
|
||||
FormatSslTime(notbefore, gmtime_r(&past, &tm));
|
||||
FormatSslTime(notafter, gmtime_r(&future, &tm));
|
||||
}
|
46
net/https/finishcertificate.c
Normal file
46
net/https/finishcertificate.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
struct Cert FinishCertificate(struct Cert *ca, mbedtls_x509write_cert *wcert,
|
||||
mbedtls_ctr_drbg_context *kr,
|
||||
mbedtls_pk_context *key) {
|
||||
int i, n, rc;
|
||||
unsigned char *p;
|
||||
mbedtls_x509_crt *cert;
|
||||
p = malloc((n = FRAMESIZE));
|
||||
i = mbedtls_x509write_crt_der(wcert, p, n, mbedtls_ctr_drbg_random, kr);
|
||||
if (i < 0) FATALF("write key (grep -0x%04x)", -i);
|
||||
cert = calloc(1, sizeof(mbedtls_x509_crt));
|
||||
mbedtls_x509_crt_parse(cert, p + n - i, i);
|
||||
if (ca) cert->next = ca->cert;
|
||||
mbedtls_x509write_crt_free(wcert);
|
||||
mbedtls_ctr_drbg_free(kr);
|
||||
free(p);
|
||||
if ((rc = mbedtls_pk_check_pair(&cert->pk, key))) {
|
||||
FATALF("generate key (grep -0x%04x)", -rc);
|
||||
}
|
||||
LogCertificate(
|
||||
gc(xasprintf("generated %s certificate", mbedtls_pk_get_name(&cert->pk))),
|
||||
cert);
|
||||
return (struct Cert){cert, key};
|
||||
}
|
26
net/https/formatx509name.c
Normal file
26
net/https/formatx509name.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
char *FormatX509Name(mbedtls_x509_name *name) {
|
||||
char *s = calloc(1, 1000);
|
||||
CHECK_GT(mbedtls_x509_dn_gets(s, 1000, name), 0);
|
||||
return s;
|
||||
}
|
30
net/https/generatecertificateserial.c
Normal file
30
net/https/generatecertificateserial.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/bignum.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
|
||||
void GenerateCertificateSerial(mbedtls_x509write_cert *wcert,
|
||||
mbedtls_ctr_drbg_context *kr) {
|
||||
mbedtls_mpi x;
|
||||
mbedtls_mpi_init(&x);
|
||||
mbedtls_mpi_fill_random(&x, 128 / 8, mbedtls_ctr_drbg_random, kr);
|
||||
mbedtls_x509write_crt_set_serial(wcert, &x);
|
||||
mbedtls_mpi_free(&x);
|
||||
}
|
26
net/https/getentropy.c
Normal file
26
net/https/getentropy.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
int GetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
CHECK_EQ(n, getrandom(p, n, 0));
|
||||
return 0;
|
||||
}
|
|
@ -1,14 +1,44 @@
|
|||
#ifndef COSMOPOLITAN_NET_HTTPS_HTTPS_H_
|
||||
#define COSMOPOLITAN_NET_HTTPS_HTTPS_H_
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/ecp.h"
|
||||
#include "third_party/mbedtls/md.h"
|
||||
#include "third_party/mbedtls/pk.h"
|
||||
#include "third_party/mbedtls/ssl_ciphersuites.h"
|
||||
#include "third_party/mbedtls/x509_crt.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct Cert {
|
||||
mbedtls_x509_crt *cert;
|
||||
mbedtls_pk_context *key;
|
||||
};
|
||||
|
||||
char *TlsError(int);
|
||||
char *DescribeSslVerifyFailure(int);
|
||||
mbedtls_x509_crt *GetSslRoots(void);
|
||||
void InitializeRng(mbedtls_ctr_drbg_context *);
|
||||
int GetEntropy(void *, unsigned char *, size_t);
|
||||
void FormatSslTime(char[restrict hasatleast 16], struct tm *);
|
||||
void ChooseCertificateLifetime(char[16], char[16]);
|
||||
void LogCertificate(const char *, mbedtls_x509_crt *);
|
||||
bool IsSelfSigned(mbedtls_x509_crt *);
|
||||
char *FormatX509Name(mbedtls_x509_name *);
|
||||
void TlsDie(const char *, int) wontreturn;
|
||||
bool ChainCertificate(mbedtls_x509_crt *, mbedtls_x509_crt *);
|
||||
bool CertHasIp(const mbedtls_x509_crt *, uint32_t);
|
||||
bool CertHasHost(const mbedtls_x509_crt *, const void *, size_t);
|
||||
bool CertHasCommonName(const mbedtls_x509_crt *, const void *, size_t);
|
||||
bool IsServerCert(const struct Cert *, mbedtls_pk_type_t);
|
||||
void TlsDebug(void *, int, const char *, int, const char *);
|
||||
|
||||
void GenerateCertificateSerial(mbedtls_x509write_cert *,
|
||||
mbedtls_ctr_drbg_context *);
|
||||
mbedtls_pk_context *InitializeKey(struct Cert *, mbedtls_x509write_cert *,
|
||||
mbedtls_md_type_t, int);
|
||||
struct Cert FinishCertificate(struct Cert *, mbedtls_x509write_cert *,
|
||||
mbedtls_ctr_drbg_context *, mbedtls_pk_context *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -27,11 +27,13 @@ NET_HTTPS_A_DIRECTDEPS = \
|
|||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_TIME \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_MBEDTLS
|
||||
|
|
35
net/https/initializekey.c
Normal file
35
net/https/initializekey.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
mbedtls_pk_context *InitializeKey(struct Cert *ca,
|
||||
mbedtls_x509write_cert *wcert,
|
||||
mbedtls_md_type_t md_alg, int type) {
|
||||
mbedtls_pk_context *k;
|
||||
mbedtls_ctr_drbg_context kr;
|
||||
k = calloc(1, sizeof(mbedtls_pk_context));
|
||||
mbedtls_x509write_crt_init(wcert);
|
||||
mbedtls_x509write_crt_set_issuer_key(wcert, ca ? ca->key : k);
|
||||
mbedtls_x509write_crt_set_subject_key(wcert, k);
|
||||
mbedtls_x509write_crt_set_md_alg(wcert, md_alg);
|
||||
mbedtls_x509write_crt_set_version(wcert, MBEDTLS_X509_CRT_VERSION_3);
|
||||
CHECK_EQ(0, mbedtls_pk_setup(k, mbedtls_pk_info_from_type(type)));
|
||||
return k;
|
||||
}
|
30
net/https/initializerng.c
Normal file
30
net/https/initializerng.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
|
||||
void InitializeRng(mbedtls_ctr_drbg_context *r) {
|
||||
volatile unsigned char b[64];
|
||||
mbedtls_ctr_drbg_init(r);
|
||||
CHECK(getrandom(b, 64, 0) == 64);
|
||||
CHECK(!mbedtls_ctr_drbg_seed(r, GetEntropy, 0, b, 64));
|
||||
mbedtls_platform_zeroize(b, 64);
|
||||
}
|
23
net/https/isselfsigned.c
Normal file
23
net/https/isselfsigned.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/https/https.h"
|
||||
|
||||
bool IsSelfSigned(mbedtls_x509_crt *cert) {
|
||||
return !mbedtls_x509_name_cmp(&cert->issuer, &cert->subject);
|
||||
}
|
29
net/https/isservercert.c
Normal file
29
net/https/isservercert.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/asn1.h"
|
||||
#include "third_party/mbedtls/oid.h"
|
||||
|
||||
bool IsServerCert(const struct Cert *cert, mbedtls_pk_type_t type) {
|
||||
return cert->cert && cert->key && !cert->cert->ca_istrue &&
|
||||
mbedtls_pk_get_type(cert->key) == type &&
|
||||
!mbedtls_x509_crt_check_extended_key_usage(
|
||||
cert->cert, MBEDTLS_OID_SERVER_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH));
|
||||
}
|
33
net/https/logcertificate.c
Normal file
33
net/https/logcertificate.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
void LogCertificate(const char *msg, mbedtls_x509_crt *cert) {
|
||||
char *s;
|
||||
size_t n;
|
||||
if (LOGGABLE(kLogDebug)) {
|
||||
if ((s = malloc((n = 15000)))) {
|
||||
if (mbedtls_x509_crt_info(s, n, " ", cert) > 0) {
|
||||
DEBUGF("%s\n%s", msg, chomp(s));
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
}
|
24
net/https/tlsdebug.c
Normal file
24
net/https/tlsdebug.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
void TlsDebug(void *c, int v, const char *f, int l, const char *s) {
|
||||
flogf(v, f, l, 0, "TLS %s", s);
|
||||
}
|
28
net/https/tlsdie.c
Normal file
28
net/https/tlsdie.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/https/https.h"
|
||||
|
||||
void TlsDie(const char *s, int r) {
|
||||
if (IsTiny()) {
|
||||
(fprintf)(stderr, "error: %s (-0x%04x %s)\n", s, -r, TlsError(r));
|
||||
} else {
|
||||
(fprintf)(stderr, "error: %s (grep -0x%04x)\n", s, -r);
|
||||
}
|
||||
exit(1);
|
||||
}
|
26
net/https/tlserror.c
Normal file
26
net/https/tlserror.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
|
||||
char *TlsError(int r) {
|
||||
static char b[128];
|
||||
mbedtls_strerror(r, b, sizeof(b));
|
||||
return b;
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/log/check.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
@ -60,18 +61,8 @@ void SetUpOnce(void) {
|
|||
close(fdin);
|
||||
}
|
||||
|
||||
void Tune(int fd, int a, int b, int x) {
|
||||
if (!b) return;
|
||||
setsockopt(fd, a, b, &x, sizeof(x));
|
||||
}
|
||||
|
||||
int Socket(void) {
|
||||
int fd;
|
||||
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) {
|
||||
Tune(fd, IPPROTO_TCP, TCP_CORK, 0);
|
||||
Tune(fd, IPPROTO_TCP, TCP_NODELAY, 1);
|
||||
}
|
||||
return fd;
|
||||
return GoodSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, false, 0);
|
||||
}
|
||||
|
||||
char *SendHttpRequest(const char *s) {
|
||||
|
|
3
third_party/getopt/getopt.c
vendored
3
third_party/getopt/getopt.c
vendored
|
@ -156,9 +156,10 @@ int getopt(int nargc, char *const nargv[], const char *ostr) {
|
|||
/* option-argument absent */
|
||||
getopt_place = kGetoptEmsg;
|
||||
if (*ostr == ':') return (BADARG);
|
||||
if (opterr)
|
||||
if (opterr) {
|
||||
fprintf(stderr, "%s%s%c\n", program_invocation_name,
|
||||
": option requires an argument -- ", optopt);
|
||||
}
|
||||
return (BADCH);
|
||||
}
|
||||
getopt_place = kGetoptEmsg;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#ifndef MBEDTLS_CHECK_H
|
||||
#define MBEDTLS_CHECK_H
|
||||
/* clang-format off */
|
||||
|
||||
#if defined(TARGET_LIKE_MBED) && \
|
||||
|
@ -16,10 +14,6 @@
|
|||
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
|
||||
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
@ -283,10 +277,6 @@
|
|||
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
|
||||
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
@ -525,11 +515,6 @@
|
|||
#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
|
||||
#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
|
||||
|
||||
#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \
|
||||
defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
|
||||
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#error "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS"
|
||||
|
@ -707,5 +692,3 @@
|
|||
* #if defined(MBEDTLS_xxx_C) that results in empty translation units.
|
||||
*/
|
||||
typedef int mbedtls_iso_c_forbids_empty_translation_units;
|
||||
|
||||
#endif /* MBEDTLS_CHECK_H */
|
5
third_party/mbedtls/config.h
vendored
5
third_party/mbedtls/config.h
vendored
|
@ -109,13 +109,12 @@
|
|||
#define MBEDTLS_ENTROPY_MAX_SOURCES 4
|
||||
#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8
|
||||
|
||||
#ifndef TINY
|
||||
/*
|
||||
* Boosts performance from 230k qps to 330k
|
||||
* Hardens against against sbox side channels
|
||||
*/
|
||||
#define MBEDTLS_AESNI_C
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
#ifndef TINY
|
||||
#define MBEDTLS_HAVE_X86_64
|
||||
#define MBEDTLS_HAVE_SSE2
|
||||
#endif
|
||||
|
@ -1263,5 +1262,5 @@
|
|||
#define MBEDTLS_HAVE_UDBL
|
||||
|
||||
#include "libc/dce.h"
|
||||
#include "third_party/mbedtls/check.h"
|
||||
#include "third_party/mbedtls/check.inc"
|
||||
#endif /* MBEDTLS_CONFIG_H_ */
|
||||
|
|
5
third_party/mbedtls/ecp.c
vendored
5
third_party/mbedtls/ecp.c
vendored
|
@ -22,6 +22,7 @@
|
|||
#include "third_party/mbedtls/bignum.h"
|
||||
#include "third_party/mbedtls/bignum_internal.h"
|
||||
#include "third_party/mbedtls/common.h"
|
||||
#include "third_party/mbedtls/config.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/ecp.h"
|
||||
#include "third_party/mbedtls/ecp_internal.h"
|
||||
|
@ -3656,10 +3657,6 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#ifndef MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
#undef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED /* >:\ */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The ECP checkup routine.
|
||||
*
|
||||
|
|
|
@ -689,7 +689,6 @@ void test_get_sequence_of( const data_t *input, int tag,
|
|||
mbedtls_test_set_step( step );
|
||||
TEST_ASSERT( cur != NULL );
|
||||
TEST_EQUAL( cur->buf.tag, tag );
|
||||
printf("yo %`'s\n", rest);
|
||||
n = strtoul( rest, (char **) &rest, 0 );
|
||||
TEST_EQUAL( n, (size_t)( cur->buf.p - input->x ) );
|
||||
++rest;
|
||||
|
|
|
@ -36,8 +36,8 @@ TOOL_BUILD_DIRECTDEPS = \
|
|||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
|
@ -50,12 +50,13 @@ TOOL_BUILD_DIRECTDEPS = \
|
|||
LIBC_TINYMATH \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_BUILD_LIB
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "libc/nexgen32e/kcpuids.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
@ -353,7 +354,7 @@ int main(int argc, char *argv[]) {
|
|||
/*
|
||||
* parse prefix arguments
|
||||
*/
|
||||
while ((opt = getopt(argc, argv, "?hntC:M:F:A:T:V:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "hntC:M:F:A:T:V:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
exit(0);
|
||||
|
@ -378,17 +379,16 @@ int main(int argc, char *argv[]) {
|
|||
case 'F':
|
||||
fszquota = sizetol(optarg, 1000);
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
write(1, MANUAL, sizeof(MANUAL) - 1);
|
||||
fputs(MANUAL, stdout);
|
||||
exit(0);
|
||||
default:
|
||||
write(2, MANUAL, sizeof(MANUAL) - 1);
|
||||
fputs(MANUAL, stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (optind == argc) {
|
||||
write(2, MANUAL, sizeof(MANUAL) - 1);
|
||||
fputs("error: missing arguments\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ TOOL_BUILD_LIB_A_DIRECTDEPS = \
|
|||
LIBC_TINYMATH \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_XED
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/ecp.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/platform.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "tool/build/lib/eztls.h"
|
||||
#include "tool/build/lib/psk.h"
|
||||
|
@ -37,34 +39,6 @@ mbedtls_ssl_config ezconf;
|
|||
mbedtls_ssl_context ezssl;
|
||||
mbedtls_ctr_drbg_context ezrng;
|
||||
|
||||
static char *EzTlsError(int r) {
|
||||
static char b[128];
|
||||
mbedtls_strerror(r, b, sizeof(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
void EzTlsDie(const char *s, int r) {
|
||||
if (IsTiny()) {
|
||||
fprintf(stderr, "error: %s (-0x%04x %s)\n", s, -r, EzTlsError(r));
|
||||
} else {
|
||||
fprintf(stderr, "error: %s (grep -0x%04x)\n", s, -r);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int EzGetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
CHECK_EQ(n, getrandom(p, n, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void EzInitializeRng(mbedtls_ctr_drbg_context *r) {
|
||||
volatile unsigned char b[64];
|
||||
mbedtls_ctr_drbg_init(r);
|
||||
CHECK(getrandom(b, 64, 0) == 64);
|
||||
CHECK(!mbedtls_ctr_drbg_seed(r, EzGetEntropy, 0, b, 64));
|
||||
mbedtls_platform_zeroize(b, 64);
|
||||
}
|
||||
|
||||
static ssize_t EzWritevAll(int fd, struct iovec *iov, int iovlen) {
|
||||
int i;
|
||||
ssize_t rc;
|
||||
|
@ -165,34 +139,38 @@ static int EzTlsRecv(void *ctx, unsigned char *buf, size_t len, uint32_t tmo) {
|
|||
return EzTlsRecvImpl(ctx, buf, len, tmo);
|
||||
}
|
||||
|
||||
void EzFd(int fd) {
|
||||
mbedtls_ssl_session_reset(&ezssl);
|
||||
mbedtls_platform_zeroize(&ezbio, sizeof(ezbio));
|
||||
ezbio.fd = fd;
|
||||
}
|
||||
|
||||
void EzHandshake(void) {
|
||||
int rc;
|
||||
while ((rc = mbedtls_ssl_handshake(&ezssl))) {
|
||||
if (rc != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
EzTlsDie("handshake failed", rc);
|
||||
TlsDie("handshake failed", rc);
|
||||
}
|
||||
}
|
||||
while ((rc = EzTlsFlush(&ezbio, 0, 0))) {
|
||||
if (rc != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
EzTlsDie("handshake flush failed", rc);
|
||||
TlsDie("handshake flush failed", rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* openssl s_client -connect 127.0.0.1:31337 \
|
||||
* -psk $(hex <~/.runit.psk) \
|
||||
* -psk_identity runit
|
||||
*/
|
||||
|
||||
void SetupPresharedKeySsl(int endpoint) {
|
||||
void EzInitialize(void) {
|
||||
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);
|
||||
EzInitializeRng(&ezrng);
|
||||
ezconf.disable_compression = 1; /* TODO(jart): Why does it behave weirdly? */
|
||||
mbedtls_ssl_config_defaults(&ezconf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_SUITEC);
|
||||
InitializeRng(&ezrng);
|
||||
}
|
||||
|
||||
void EzSetup(char psk[32]) {
|
||||
int rc;
|
||||
mbedtls_ssl_conf_rng(&ezconf, mbedtls_ctr_drbg_random, &ezrng);
|
||||
DCHECK_EQ(0, mbedtls_ssl_conf_psk(&ezconf, GetRunitPsk(), 32, "runit", 5));
|
||||
DCHECK_EQ(0, mbedtls_ssl_setup(&ezssl, &ezconf));
|
||||
if ((rc = mbedtls_ssl_conf_psk(&ezconf, psk, 32, "runit", 5)) ||
|
||||
(rc = mbedtls_ssl_setup(&ezssl, &ezconf))) {
|
||||
TlsDie("EzSetup", rc);
|
||||
}
|
||||
mbedtls_ssl_set_bio(&ezssl, &ezbio, EzTlsSend, 0, EzTlsRecv);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define COSMOPOLITAN_TOOL_BUILD_LIB_EZTLS_H_
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "third_party/mbedtls/x509_crt.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
@ -17,11 +18,24 @@ extern mbedtls_ssl_config ezconf;
|
|||
extern mbedtls_ssl_context ezssl;
|
||||
extern mbedtls_ctr_drbg_context ezrng;
|
||||
|
||||
void EzFd(int);
|
||||
void EzHandshake(void);
|
||||
void SetupPresharedKeySsl(int);
|
||||
void EzTlsDie(const char *, int) wontreturn;
|
||||
void EzSetup(char[32]);
|
||||
void EzInitialize(void);
|
||||
int EzTlsFlush(struct EzTlsBio *, const unsigned char *, size_t);
|
||||
|
||||
/*
|
||||
* openssl s_client -connect 127.0.0.1:31337 \
|
||||
* -psk $(hex <~/.runit.psk) \
|
||||
* -psk_identity runit
|
||||
*/
|
||||
forceinline void SetupPresharedKeySsl(int endpoint, char psk[32]) {
|
||||
EzInitialize();
|
||||
mbedtls_ssl_config_defaults(&ezconf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_SUITEC);
|
||||
EzSetup(psk);
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_EZTLS_H_ */
|
||||
|
|
|
@ -42,8 +42,10 @@
|
|||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "tool/build/lib/eztls.h"
|
||||
#include "tool/build/lib/psk.h"
|
||||
#include "tool/build/runit.h"
|
||||
|
||||
/**
|
||||
|
@ -336,7 +338,7 @@ bool Recv(unsigned char *p, size_t n) {
|
|||
usleep((backoff = (backoff + 1000) * 2));
|
||||
return false;
|
||||
} else if (rc < 0) {
|
||||
EzTlsDie("read response failed", rc);
|
||||
TlsDie("read response failed", rc);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -387,9 +389,8 @@ int RunOnHost(char *spec) {
|
|||
1);
|
||||
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
|
||||
do {
|
||||
mbedtls_ssl_session_reset(&ezssl);
|
||||
Connect();
|
||||
ezbio.fd = g_sock;
|
||||
EzFd(g_sock);
|
||||
EzHandshake();
|
||||
SendRequest();
|
||||
} while ((rc = ReadResponse()) == -1);
|
||||
|
@ -454,7 +455,7 @@ int RunRemoteTestsInParallel(char *hosts[], int count) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
showcrashreports();
|
||||
SetupPresharedKeySsl(MBEDTLS_SSL_IS_CLIENT);
|
||||
SetupPresharedKeySsl(MBEDTLS_SSL_IS_CLIENT, GetRunitPsk());
|
||||
/* __log_level = kLogDebug; */
|
||||
if (argc > 1 &&
|
||||
(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
|
||||
|
|
|
@ -45,9 +45,11 @@
|
|||
#include "libc/sysv/consts/w.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "tool/build/lib/eztls.h"
|
||||
#include "tool/build/lib/psk.h"
|
||||
#include "tool/build/runit.h"
|
||||
|
||||
/**
|
||||
|
@ -264,13 +266,13 @@ void HandleClient(void) {
|
|||
close(g_clifd);
|
||||
return;
|
||||
}
|
||||
ezbio.fd = g_clifd;
|
||||
EzFd(g_clifd);
|
||||
EzHandshake();
|
||||
addrstr = gc(DescribeAddress(&addr));
|
||||
DEBUGF("%s %s %s", gc(DescribeAddress(&g_servaddr)), "accepted", addrstr);
|
||||
while ((got = mbedtls_ssl_read(&ezssl, (p = g_buf), sizeof(g_buf))) < 0) {
|
||||
if (got != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
EzTlsDie("ssl read failed", got);
|
||||
TlsDie("ssl read failed", got);
|
||||
}
|
||||
}
|
||||
CHECK_GE(got, kMinMsgSize);
|
||||
|
@ -302,7 +304,7 @@ void HandleClient(void) {
|
|||
while (remaining) {
|
||||
while ((got = mbedtls_ssl_read(&ezssl, g_buf, sizeof(g_buf))) < 0) {
|
||||
if (got != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
EzTlsDie("ssl read failed", got);
|
||||
TlsDie("ssl read failed", got);
|
||||
}
|
||||
}
|
||||
CHECK_LE(got, remaining);
|
||||
|
@ -443,7 +445,7 @@ void Daemonize(void) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
showcrashreports();
|
||||
SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER);
|
||||
SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER, GetRunitPsk());
|
||||
/* __log_level = kLogDebug; */
|
||||
GetOpts(argc, argv);
|
||||
CHECK_NE(-1, (g_devnullfd = open("/dev/null", O_RDWR)));
|
||||
|
|
|
@ -124,34 +124,10 @@ void GetOpts(int *argc, char ***argv) {
|
|||
CHECK_NOTNULL(outpath_);
|
||||
}
|
||||
|
||||
bool IsUtf8(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p + 2 <= pe; ++p) {
|
||||
if (p[0] >= 0300) {
|
||||
if (p[1] >= 0200 && p[1] < 0300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsText(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p < pe; ++p) {
|
||||
if (*p <= 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShouldCompress(const char *name, size_t namesize,
|
||||
const unsigned char *data, size_t datasize) {
|
||||
return !nocompress_ && datasize >= 64 && !IsNoCompressExt(name, namesize) &&
|
||||
(datasize < 1000 || MeasureEntropy((void *)data, 1000) < 6);
|
||||
(datasize < 1000 || MeasureEntropy((void *)data, 1000) < 7);
|
||||
}
|
||||
|
||||
void GetDosLocalTime(int64_t utcunixts, uint16_t *out_time,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/math.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
|
@ -50,10 +51,12 @@
|
|||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/hex.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
@ -106,6 +109,7 @@
|
|||
#include "third_party/mbedtls/entropy_poll.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/iana.h"
|
||||
#include "third_party/mbedtls/md.h"
|
||||
#include "third_party/mbedtls/md5.h"
|
||||
#include "third_party/mbedtls/oid.h"
|
||||
#include "third_party/mbedtls/pk.h"
|
||||
|
@ -267,10 +271,7 @@ static struct Suites {
|
|||
|
||||
static struct Certs {
|
||||
size_t n;
|
||||
struct Cert {
|
||||
mbedtls_x509_crt *cert;
|
||||
mbedtls_pk_context *key;
|
||||
} * p;
|
||||
struct Cert *p;
|
||||
} certs;
|
||||
|
||||
static struct Redirects {
|
||||
|
@ -480,39 +481,6 @@ static long ParseInt(const char *s) {
|
|||
return strtol(s, 0, 0);
|
||||
}
|
||||
|
||||
forceinline bool SlicesEqual(const char *a, size_t n, const char *b, size_t m) {
|
||||
return n == m && !memcmp(a, b, n);
|
||||
}
|
||||
|
||||
forceinline bool SlicesEqualCase(const void *a, size_t n, const void *b,
|
||||
size_t m) {
|
||||
return n == m && !memcasecmp(a, b, n);
|
||||
}
|
||||
|
||||
static int CompareSlices(const char *a, size_t n, const char *b, size_t m) {
|
||||
int c;
|
||||
if ((c = memcmp(a, b, MIN(n, m)))) return c;
|
||||
if (n < m) return -1;
|
||||
if (n > m) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareSlicesCase(const char *a, size_t n, const char *b, size_t m) {
|
||||
int c;
|
||||
if ((c = memcasecmp(a, b, MIN(n, m)))) return c;
|
||||
if (n < m) return -1;
|
||||
if (n > m) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool StartsWithIgnoreCase(const char *s, const char *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (kToLower[*s++ & 255] != (*prefix++ & 255)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void *FreeLater(void *p) {
|
||||
if (p) {
|
||||
if (++freelist.n > freelist.c) {
|
||||
|
@ -587,28 +555,6 @@ static long FindRedirect(const char *s, size_t n) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void LogCertificate(const char *msg, mbedtls_x509_crt *cert) {
|
||||
char *s;
|
||||
size_t n;
|
||||
if (LOGGABLE(kLogDebug)) {
|
||||
if ((s = gc(malloc((n = 15000))))) {
|
||||
if (mbedtls_x509_crt_info(s, n, " ", cert) > 0) {
|
||||
DEBUGF("%s\n%s", msg, chomp(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *FormatX509Name(mbedtls_x509_name *name) {
|
||||
char *s = calloc(1, 1000);
|
||||
CHECK_GT(mbedtls_x509_dn_gets(s, 1000, name), 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool IsSelfSigned(mbedtls_x509_crt *cert) {
|
||||
return !mbedtls_x509_name_cmp(&cert->issuer, &cert->subject);
|
||||
}
|
||||
|
||||
static mbedtls_x509_crt *GetTrustedCertificate(mbedtls_x509_name *name) {
|
||||
size_t i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
|
@ -628,20 +574,6 @@ static void UseCertificate(mbedtls_ssl_config *c, struct Cert *kp,
|
|||
CHECK_EQ(0, mbedtls_ssl_conf_own_cert(c, kp->cert, kp->key));
|
||||
}
|
||||
|
||||
static bool ChainCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *parent) {
|
||||
if (!mbedtls_x509_crt_check_signature(cert, parent, 0)) {
|
||||
DEBUGF("chaining %`'s to %`'s", gc(FormatX509Name(&cert->subject)),
|
||||
gc(FormatX509Name(&parent->subject)));
|
||||
cert->next = parent;
|
||||
return true;
|
||||
} else {
|
||||
WARNF("signature check failed for %`'s -> %`'s",
|
||||
gc(FormatX509Name(&cert->subject)),
|
||||
gc(FormatX509Name(&parent->subject)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void AppendCert(mbedtls_x509_crt *cert, mbedtls_pk_context *key) {
|
||||
certs.p = realloc(certs.p, ++certs.n * sizeof(*certs.p));
|
||||
certs.p[certs.n - 1].cert = cert;
|
||||
|
@ -1179,34 +1111,6 @@ static void ReportWorkerExit(int pid, int ws) {
|
|||
}
|
||||
}
|
||||
|
||||
static void AddTimeval(struct timeval *x, const struct timeval *y) {
|
||||
x->tv_sec += y->tv_sec;
|
||||
x->tv_usec += y->tv_usec;
|
||||
if (x->tv_usec >= 1000000) {
|
||||
x->tv_usec -= 1000000;
|
||||
x->tv_sec += 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddRusage(struct rusage *x, const struct rusage *y) {
|
||||
AddTimeval(&x->ru_utime, &y->ru_utime);
|
||||
AddTimeval(&x->ru_stime, &y->ru_stime);
|
||||
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
|
||||
x->ru_ixrss += y->ru_ixrss;
|
||||
x->ru_idrss += y->ru_idrss;
|
||||
x->ru_isrss += y->ru_isrss;
|
||||
x->ru_minflt += y->ru_minflt;
|
||||
x->ru_majflt += y->ru_majflt;
|
||||
x->ru_nswap += y->ru_nswap;
|
||||
x->ru_inblock += y->ru_inblock;
|
||||
x->ru_oublock += y->ru_oublock;
|
||||
x->ru_msgsnd += y->ru_msgsnd;
|
||||
x->ru_msgrcv += y->ru_msgrcv;
|
||||
x->ru_nsignals += y->ru_nsignals;
|
||||
x->ru_nvcsw += y->ru_nvcsw;
|
||||
x->ru_nivcsw += y->ru_nivcsw;
|
||||
}
|
||||
|
||||
static void ReportWorkerResources(int pid, struct rusage *ru) {
|
||||
char *s, *b = 0;
|
||||
if (logrusage || LOGGABLE(kLogDebug)) {
|
||||
|
@ -1389,11 +1293,6 @@ static int TlsRecv(void *ctx, unsigned char *buf, size_t len, uint32_t tmo) {
|
|||
return TlsRecvImpl(ctx, buf, len, tmo);
|
||||
}
|
||||
|
||||
static void TlsDebug(void *ctx, int level, const char *file, int line,
|
||||
const char *message) {
|
||||
flogf(level, file, line, 0, "TLS %s", message);
|
||||
}
|
||||
|
||||
static ssize_t SslRead(int fd, void *buf, size_t size) {
|
||||
int rc;
|
||||
rc = mbedtls_ssl_read(&ssl, buf, size);
|
||||
|
@ -1473,12 +1372,11 @@ static void WipeServingKeys(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool CertHasCommonName(const mbedtls_x509_crt *cert,
|
||||
const unsigned char *host, size_t size) {
|
||||
bool CertHasCommonName(const mbedtls_x509_crt *cert, const void *s, size_t n) {
|
||||
const mbedtls_x509_name *name;
|
||||
for (name = &cert->subject; name; name = name->next) {
|
||||
if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid)) {
|
||||
if (SlicesEqualCase(host, size, name->val.p, name->val.len)) {
|
||||
if (SlicesEqualCase(s, n, name->val.p, name->val.len)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
@ -1487,44 +1385,11 @@ static bool CertHasCommonName(const mbedtls_x509_crt *cert,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool CertHasHost(const mbedtls_x509_crt *cert, const unsigned char *host,
|
||||
size_t size) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
SlicesEqualCase(host, size, cur->buf.p, cur->buf.len)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CertHasIp(const mbedtls_x509_crt *cert, uint32_t ip) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_IP_ADDRESS &&
|
||||
cur->buf.len == 4 && ip == READ32BE(cur->buf.p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsServerCert(mbedtls_pk_type_t type, int i) {
|
||||
return certs.p[i].cert && certs.p[i].key && !certs.p[i].cert->ca_istrue &&
|
||||
mbedtls_pk_get_type(certs.p[i].key) == type &&
|
||||
!mbedtls_x509_crt_check_extended_key_usage(
|
||||
certs.p[i].cert, MBEDTLS_OID_SERVER_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH));
|
||||
}
|
||||
|
||||
static bool TlsRouteFind(mbedtls_pk_type_t type, mbedtls_ssl_context *ssl,
|
||||
const unsigned char *host, size_t size, int64_t ip) {
|
||||
int i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (IsServerCert(type, i) &&
|
||||
if (IsServerCert(certs.p + i, type) &&
|
||||
(((certs.p[i].cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) &&
|
||||
(ip == -1 ? CertHasHost(certs.p[i].cert, host, size)
|
||||
: CertHasIp(certs.p[i].cert, ip))) ||
|
||||
|
@ -1543,7 +1408,7 @@ static bool TlsRouteFind(mbedtls_pk_type_t type, mbedtls_ssl_context *ssl,
|
|||
static bool TlsRouteFirst(mbedtls_pk_type_t type, mbedtls_ssl_context *ssl) {
|
||||
int i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (IsServerCert(type, i)) {
|
||||
if (IsServerCert(certs.p + i, type)) {
|
||||
CHECK_EQ(
|
||||
0, mbedtls_ssl_set_hs_own_cert(ssl, certs.p[i].cert, certs.p[i].key));
|
||||
DEBUGF("TlsRoute(%s) %s %`'s", mbedtls_pk_type_name(type),
|
||||
|
@ -1679,40 +1544,6 @@ static bool TlsSetup(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static int GetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
CHECK_EQ(n, getrandom(p, n, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitializeRng(mbedtls_ctr_drbg_context *r) {
|
||||
volatile unsigned char b[64];
|
||||
mbedtls_ctr_drbg_init(r);
|
||||
CHECK(getrandom(b, 64, 0) == 64);
|
||||
CHECK(!mbedtls_ctr_drbg_seed(r, GetEntropy, 0, b, 64));
|
||||
mbedtls_platform_zeroize(b, 64);
|
||||
}
|
||||
|
||||
static void GenerateSerial(mbedtls_x509write_cert *wcert,
|
||||
mbedtls_ctr_drbg_context *kr) {
|
||||
mbedtls_mpi x;
|
||||
mbedtls_mpi_init(&x);
|
||||
mbedtls_mpi_fill_random(&x, 128 / 8, mbedtls_ctr_drbg_random, kr);
|
||||
mbedtls_x509write_crt_set_serial(wcert, &x);
|
||||
mbedtls_mpi_free(&x);
|
||||
}
|
||||
|
||||
static void ChooseCertificateLifetime(char notbefore[16], char notafter[16]) {
|
||||
struct tm tm;
|
||||
int64_t past, now, future, lifetime, tolerance;
|
||||
tolerance = 60 * 60 * 24;
|
||||
lifetime = 60 * 60 * 24 * 365;
|
||||
now = nowl();
|
||||
past = now - tolerance;
|
||||
future = now + tolerance + lifetime;
|
||||
FormatSslTime(notbefore, gmtime_r(&past, &tm));
|
||||
FormatSslTime(notafter, gmtime_r(&future, &tm));
|
||||
}
|
||||
|
||||
static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
||||
int usage, int type) {
|
||||
int r;
|
||||
|
@ -1766,8 +1597,10 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
if ((r = mbedtls_x509write_crt_set_subject_alternative_name(cw, san, nsan)) ||
|
||||
(r = mbedtls_x509write_crt_set_validity(cw, notbefore, notafter)) ||
|
||||
(r = mbedtls_x509write_crt_set_basic_constraints(cw, false, -1)) ||
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
(r = mbedtls_x509write_crt_set_subject_key_identifier(cw)) ||
|
||||
(r = mbedtls_x509write_crt_set_authority_key_identifier(cw)) ||
|
||||
#endif
|
||||
(r = mbedtls_x509write_crt_set_key_usage(cw, usage)) ||
|
||||
(r = mbedtls_x509write_crt_set_ext_key_usage(cw, type)) ||
|
||||
(r = mbedtls_x509write_crt_set_subject_name(cw, subject)) ||
|
||||
|
@ -1794,57 +1627,18 @@ static struct Cert GetKeySigningKey(void) {
|
|||
return (struct Cert){0};
|
||||
}
|
||||
|
||||
static mbedtls_pk_context *InitializeKey(struct Cert *ca,
|
||||
mbedtls_x509write_cert *wcert,
|
||||
int type) {
|
||||
mbedtls_pk_context *k;
|
||||
mbedtls_ctr_drbg_context kr;
|
||||
k = calloc(1, sizeof(mbedtls_pk_context));
|
||||
mbedtls_x509write_crt_init(wcert);
|
||||
mbedtls_x509write_crt_set_issuer_key(wcert, ca ? ca->key : k);
|
||||
mbedtls_x509write_crt_set_subject_key(wcert, k);
|
||||
mbedtls_x509write_crt_set_md_alg(
|
||||
wcert, suiteb ? MBEDTLS_MD_SHA384 : MBEDTLS_MD_SHA256);
|
||||
mbedtls_x509write_crt_set_version(wcert, MBEDTLS_X509_CRT_VERSION_3);
|
||||
CHECK_EQ(0, mbedtls_pk_setup(k, mbedtls_pk_info_from_type(type)));
|
||||
return k;
|
||||
}
|
||||
|
||||
static struct Cert FinishCertificate(struct Cert *ca,
|
||||
mbedtls_x509write_cert *wcert,
|
||||
mbedtls_ctr_drbg_context *kr,
|
||||
mbedtls_pk_context *key) {
|
||||
int i, n, rc;
|
||||
unsigned char *p;
|
||||
mbedtls_x509_crt *cert;
|
||||
p = malloc((n = FRAMESIZE));
|
||||
i = mbedtls_x509write_crt_der(wcert, p, n, mbedtls_ctr_drbg_random, kr);
|
||||
if (i < 0) FATALF("write key (grep -0x%04x)", -i);
|
||||
cert = calloc(1, sizeof(mbedtls_x509_crt));
|
||||
mbedtls_x509_crt_parse(cert, p + n - i, i);
|
||||
if (ca) cert->next = ca->cert;
|
||||
mbedtls_x509write_crt_free(wcert);
|
||||
mbedtls_ctr_drbg_free(kr);
|
||||
free(p);
|
||||
if ((rc = mbedtls_pk_check_pair(&cert->pk, key))) {
|
||||
FATALF("generate key (grep -0x%04x)", -rc);
|
||||
}
|
||||
LogCertificate(
|
||||
gc(xasprintf("generated %s certificate", mbedtls_pk_get_name(&cert->pk))),
|
||||
cert);
|
||||
return (struct Cert){cert, key};
|
||||
}
|
||||
|
||||
static struct Cert GenerateEcpCertificate(struct Cert *ca) {
|
||||
mbedtls_pk_context *key;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_ctr_drbg_context kr;
|
||||
mbedtls_x509write_cert wcert;
|
||||
InitializeRng(&kr);
|
||||
key = InitializeKey(ca, &wcert, MBEDTLS_PK_ECKEY);
|
||||
md_alg = suiteb ? MBEDTLS_MD_SHA384 : MBEDTLS_MD_SHA256;
|
||||
key = InitializeKey(ca, &wcert, md_alg, MBEDTLS_PK_ECKEY);
|
||||
CHECK_EQ(0, mbedtls_ecp_gen_key(
|
||||
suiteb ? MBEDTLS_ECP_DP_SECP384R1 : MBEDTLS_ECP_DP_SECP256R1,
|
||||
mbedtls_pk_ec(*key), mbedtls_ctr_drbg_random, &kr));
|
||||
GenerateSerial(&wcert, &kr);
|
||||
GenerateCertificateSerial(&wcert, &kr);
|
||||
ConfigureCertificate(&wcert, ca, MBEDTLS_X509_KU_DIGITAL_SIGNATURE,
|
||||
MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER |
|
||||
MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT);
|
||||
|
@ -1853,13 +1647,15 @@ static struct Cert GenerateEcpCertificate(struct Cert *ca) {
|
|||
|
||||
static struct Cert GenerateRsaCertificate(struct Cert *ca) {
|
||||
mbedtls_pk_context *key;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_ctr_drbg_context kr;
|
||||
mbedtls_x509write_cert wcert;
|
||||
InitializeRng(&kr);
|
||||
key = InitializeKey(ca, &wcert, MBEDTLS_PK_RSA);
|
||||
md_alg = suiteb ? MBEDTLS_MD_SHA384 : MBEDTLS_MD_SHA256;
|
||||
key = InitializeKey(ca, &wcert, md_alg, MBEDTLS_PK_RSA);
|
||||
CHECK_EQ(0, mbedtls_rsa_gen_key(mbedtls_pk_rsa(*key), mbedtls_ctr_drbg_random,
|
||||
&kr, suiteb ? 4096 : 2048, 65537));
|
||||
GenerateSerial(&wcert, &kr);
|
||||
GenerateCertificateSerial(&wcert, &kr);
|
||||
ConfigureCertificate(
|
||||
&wcert, ca,
|
||||
MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_ENCIPHERMENT,
|
||||
|
@ -1942,65 +1738,6 @@ static int64_t GetGmtOffset(int64_t t) {
|
|||
return tm.tm_gmtoff;
|
||||
}
|
||||
|
||||
static int64_t LocoTimeToZulu(int64_t x) {
|
||||
return x - gmtoff;
|
||||
}
|
||||
|
||||
static int64_t GetZipCfileLastModified(const uint8_t *zcf) {
|
||||
const uint8_t *p, *pe;
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraNtfs &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 4) == 1 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 8) {
|
||||
return READ64LE(ZIP_EXTRA_CONTENT(p) + 8) / HECTONANOSECONDS -
|
||||
MODERNITYSECONDS; /* TODO(jart): update access time */
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraExtendedTimestamp &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 1 + 4 && (*ZIP_EXTRA_CONTENT(p) & 1)) {
|
||||
return (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 1);
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraUnix &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4) {
|
||||
return (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 4);
|
||||
}
|
||||
}
|
||||
return LocoTimeToZulu(DosDateTimeToUnix(ZIP_CFILE_LASTMODIFIEDDATE(zcf),
|
||||
ZIP_CFILE_LASTMODIFIEDTIME(zcf)));
|
||||
}
|
||||
|
||||
static int64_t GetZipCfileCreation(const uint8_t *zcf) {
|
||||
const uint8_t *p, *pe;
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraNtfs &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 3 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 4) == 1 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 24) {
|
||||
return READ64LE(ZIP_EXTRA_CONTENT(p) + 8 + 8 + 8) / HECTONANOSECONDS -
|
||||
MODERNITYSECONDS;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraExtendedTimestamp &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 1 && (*ZIP_EXTRA_CONTENT(p) & 4) &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >=
|
||||
1 + popcnt((*ZIP_EXTRA_CONTENT(p) & 7)) * 4) {
|
||||
return (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
popcnt((*ZIP_EXTRA_CONTENT(p) & 3)) * 4);
|
||||
}
|
||||
}
|
||||
return GetZipCfileLastModified(zcf);
|
||||
}
|
||||
|
||||
forceinline bool IsCompressed(struct Asset *a) {
|
||||
return !a->file &&
|
||||
ZIP_LFILE_COMPRESSIONMETHOD(zbase + a->lf) == kZipCompressionDeflate;
|
||||
|
@ -2054,9 +1791,9 @@ static void FreeStrings(struct Strings *l) {
|
|||
}
|
||||
|
||||
static void IndexAssets(void) {
|
||||
int64_t lm;
|
||||
uint64_t cf;
|
||||
struct Asset *p;
|
||||
struct timespec lm;
|
||||
uint32_t i, n, m, step, hash;
|
||||
DEBUGF("indexing assets (inode %#lx)", zst.st_ino);
|
||||
CHECK_GE(HASH_LOAD_FACTOR, 2);
|
||||
|
@ -2080,13 +1817,13 @@ static void IndexAssets(void) {
|
|||
i = (hash + (step * (step + 1)) >> 1) & (m - 1);
|
||||
++step;
|
||||
} while (p[i].hash);
|
||||
lm = GetZipCfileLastModified(zbase + cf);
|
||||
GetZipCfileTimestamps(zbase + cf, &lm, 0, 0, gmtoff);
|
||||
p[i].hash = hash;
|
||||
p[i].cf = cf;
|
||||
p[i].lf = GetZipCfileOffset(zbase + cf);
|
||||
p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zbase + cf) & kZipIattrText);
|
||||
p[i].lastmodified = lm;
|
||||
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm);
|
||||
p[i].lastmodified = lm.tv_sec;
|
||||
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm.tv_sec);
|
||||
}
|
||||
assets.p = p;
|
||||
assets.n = m;
|
||||
|
@ -2891,9 +2628,9 @@ static char *ServeListing(void) {
|
|||
uint8_t *zcf;
|
||||
struct tm tm;
|
||||
const char *and;
|
||||
int64_t lastmod;
|
||||
struct rusage ru;
|
||||
char *p, *q, *path;
|
||||
struct timespec lastmod;
|
||||
char rb[8], tb[20], *rp[6];
|
||||
size_t i, n, pathlen, rn[6];
|
||||
LockInc(&shared->c.listingrequests);
|
||||
|
@ -2951,8 +2688,8 @@ td { padding-right: 3em; }\r\n\
|
|||
ZIP_CFILE_COMMENT(zcf),
|
||||
strnlen(ZIP_CFILE_COMMENT(zcf), ZIP_CFILE_COMMENTSIZE(zcf)), &rn[3]);
|
||||
rp[4] = EscapeHtml(rp[0], rn[0], &rn[4]);
|
||||
lastmod = GetZipCfileLastModified(zcf);
|
||||
localtime_r(&lastmod, &tm);
|
||||
GetZipCfileTimestamps(zcf, &lastmod, 0, 0, gmtoff);
|
||||
localtime_r(&lastmod.tv_sec, &tm);
|
||||
iso8601(tb, &tm);
|
||||
if (IsCompressionMethodSupported(ZIP_CFILE_COMPRESSIONMETHOD(zcf)) &&
|
||||
IsAcceptablePath(path, pathlen)) {
|
||||
|
@ -3421,30 +3158,6 @@ static void GetDosLocalTime(int64_t utcunixts, uint16_t *out_time,
|
|||
*out_date = DOS_DATE(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday + 1);
|
||||
}
|
||||
|
||||
static bool IsUtf8(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p + 2 <= pe; ++p) {
|
||||
if (p[0] >= 0300) {
|
||||
if (p[1] >= 0200 && p[1] < 0300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsText(const void *data, size_t size) {
|
||||
const unsigned char *p, *pe;
|
||||
for (p = data, pe = p + size; p < pe; ++p) {
|
||||
if (*p <= 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int LuaStoreAsset(lua_State *L) {
|
||||
int64_t ft;
|
||||
int i, mode;
|
||||
|
@ -3646,12 +3359,6 @@ static void ReseedRng(mbedtls_ctr_drbg_context *r, const char *s) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static char *TlsError(int r) {
|
||||
static char b[128];
|
||||
mbedtls_strerror(r, b, sizeof(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static wontreturn void LuaThrowTlsError(lua_State *L, const char *s, int r) {
|
||||
const char *code;
|
||||
code = gc(xasprintf("-0x%04x", -r));
|
||||
|
@ -3663,35 +3370,6 @@ static wontreturn void LuaThrowTlsError(lua_State *L, const char *s, int r) {
|
|||
unreachable;
|
||||
}
|
||||
|
||||
static bool Tune(int fd, int a, int b, int x) {
|
||||
if (!b) return false;
|
||||
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
|
||||
}
|
||||
|
||||
static int Socket(int family, int type, int protocol, bool isserver) {
|
||||
int fd;
|
||||
if ((fd = socket(family, type, protocol)) != -1) {
|
||||
if (isserver) {
|
||||
Tune(fd, SOL_TCP, TCP_FASTOPEN, 100);
|
||||
Tune(fd, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
} else {
|
||||
Tune(fd, SOL_TCP, TCP_FASTOPEN_CONNECT, 1);
|
||||
}
|
||||
if (!Tune(fd, SOL_TCP, TCP_QUICKACK, 1)) {
|
||||
Tune(fd, SOL_TCP, TCP_NODELAY, 1);
|
||||
}
|
||||
if (timeout.tv_sec < 0) {
|
||||
Tune(fd, SOL_SOCKET, SO_KEEPALIVE, 1);
|
||||
Tune(fd, SOL_TCP, TCP_KEEPIDLE, -timeout.tv_sec);
|
||||
Tune(fd, SOL_TCP, TCP_KEEPINTVL, -timeout.tv_sec);
|
||||
} else {
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static char *FoldHeader(struct HttpMessage *msg, char *b, int h, size_t *z) {
|
||||
char *p;
|
||||
size_t i, n, m;
|
||||
|
@ -3924,8 +3602,8 @@ static int LuaFetch(lua_State *L) {
|
|||
ip = ntohl(((struct sockaddr_in *)addr->ai_addr)->sin_addr.s_addr);
|
||||
DEBUGF("client connecting %hhu.%hhu.%hhu.%hhu:%d", ip >> 24, ip >> 16,
|
||||
ip >> 8, ip, ntohs(((struct sockaddr_in *)addr->ai_addr)->sin_port));
|
||||
CHECK_NE(-1, (sock = Socket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol, false)));
|
||||
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol, false, &timeout)));
|
||||
if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
|
||||
close(sock);
|
||||
luaL_error(L, "connect(%s:%s) failed: %s", host, port, strerror(errno));
|
||||
|
@ -5168,13 +4846,17 @@ static int LuaGetLastModifiedTime(lua_State *L) {
|
|||
size_t pathlen;
|
||||
struct Asset *a;
|
||||
const char *path;
|
||||
struct timespec lm;
|
||||
int64_t zuluseconds;
|
||||
path = LuaCheckPath(L, 1, &pathlen);
|
||||
if ((a = GetAsset(path, pathlen))) {
|
||||
if (a->file) {
|
||||
lua_pushinteger(L, a->file->st.st_mtim.tv_sec);
|
||||
zuluseconds = a->file->st.st_mtim.tv_sec;
|
||||
} else {
|
||||
lua_pushinteger(L, GetZipCfileLastModified(zbase + a->cf));
|
||||
GetZipCfileTimestamps(zbase + a->cf, &lm, 0, 0, gmtoff);
|
||||
zuluseconds = lm.tv_sec;
|
||||
}
|
||||
lua_pushinteger(L, zuluseconds);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
@ -6216,8 +5898,8 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) {
|
|||
}
|
||||
} else if (!IsTiny() && msg.method != kHttpHead && !IsSslCompressed() &&
|
||||
ClientAcceptsGzip() &&
|
||||
((contentlength >= 100 && StartsWithIgnoreCase(ct, "text/")) ||
|
||||
(contentlength >= 1000 && MeasureEntropy(content, 1000) < 6))) {
|
||||
((contentlength >= 100 && startswithi(ct, "text/")) ||
|
||||
(contentlength >= 1000 && MeasureEntropy(content, 1000) < 7))) {
|
||||
p = ServeAssetCompressed(a);
|
||||
} else {
|
||||
p = ServeAssetIdentity(a, ct);
|
||||
|
@ -6725,8 +6407,8 @@ static void Listen(void) {
|
|||
servers.p[n].addr.sin_family = AF_INET;
|
||||
servers.p[n].addr.sin_port = htons(ports.p[j]);
|
||||
servers.p[n].addr.sin_addr.s_addr = htonl(ips.p[i]);
|
||||
if ((servers.p[n].fd = Socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC,
|
||||
IPPROTO_TCP, true)) == -1) {
|
||||
if ((servers.p[n].fd = GoodSocket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC,
|
||||
IPPROTO_TCP, true, &timeout)) == -1) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
|
@ -109,37 +111,6 @@ void OnInt(int sig) {
|
|||
isdone = true;
|
||||
}
|
||||
|
||||
static inline bool SlicesEqualCase(const char *a, size_t n, const char *b,
|
||||
size_t m) {
|
||||
return n == m && !memcasecmp(a, b, n);
|
||||
}
|
||||
|
||||
static int GetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
rngset(p, n, rand64, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool TuneSocket(int fd, int a, int b, int x) {
|
||||
if (!b) return false;
|
||||
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
|
||||
}
|
||||
|
||||
static int Socket(int family, int type, int protocol) {
|
||||
int fd;
|
||||
if ((fd = socket(family, type, protocol)) != -1) {
|
||||
/* TuneSocket(fd, SOL_SOCKET, SO_KEEPALIVE, 1); */
|
||||
/* if (protocol == SOL_TCP) { */
|
||||
/* TuneSocket(fd, SOL_TCP, TCP_KEEPIDLE, 60); */
|
||||
/* TuneSocket(fd, SOL_TCP, TCP_KEEPINTVL, 60); */
|
||||
/* TuneSocket(fd, SOL_TCP, TCP_FASTOPEN_CONNECT, 1); */
|
||||
/* if (!TuneSocket(fd, SOL_TCP, TCP_QUICKACK, 1)) { */
|
||||
/* TuneSocket(fd, SOL_TCP, TCP_NODELAY, 1); */
|
||||
/* } */
|
||||
/* } */
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int TlsSend(void *c, const unsigned char *p, size_t n) {
|
||||
int rc;
|
||||
if ((rc = write(*(int *)c, p, n)) == -1) {
|
||||
|
@ -174,21 +145,6 @@ static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
|
|||
return r;
|
||||
}
|
||||
|
||||
static char *TlsError(int r) {
|
||||
static char b[128];
|
||||
mbedtls_strerror(r, b, sizeof(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static wontreturn void TlsDie(const char *s, int r) {
|
||||
if (IsTiny()) {
|
||||
fprintf(stderr, "error: %s (-0x%04x %s)\n", s, -r, TlsError(r));
|
||||
} else {
|
||||
fprintf(stderr, "error: %s (grep -0x%04x)\n", s, -r);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
||||
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
|
||||
exit(rc);
|
||||
|
@ -219,8 +175,8 @@ int fetch(void) {
|
|||
*/
|
||||
InitHttpMessage(&msg, kHttpResponse);
|
||||
ip = ntohl(((struct sockaddr_in *)addr->ai_addr)->sin_addr.s_addr);
|
||||
CHECK_NE(-1, (sock = Socket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol)));
|
||||
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol, false, 0)));
|
||||
if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
|
||||
goto TransportError;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue