mirror of
https://github.com/jedisct1/minisign.git
synced 2025-04-04 19:37:48 +03:00
250 lines
4.7 KiB
C
250 lines
4.7 KiB
C
|
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
|
# include <sys/types.h>
|
|
# include <sys/stat.h>
|
|
# include <fcntl.h>
|
|
#elif defined(_WIN32)
|
|
# include <direct.h>
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <sodium.h>
|
|
|
|
#include "base64.h"
|
|
#include "helpers.h"
|
|
|
|
uint64_t
|
|
le64_load(const unsigned char *p)
|
|
{
|
|
return ((uint64_t)(p[0])) | ((uint64_t)(p[1]) << 8) |
|
|
((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
|
|
((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
|
|
((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
|
|
}
|
|
|
|
void
|
|
le64_store(unsigned char *p, uint64_t x)
|
|
{
|
|
p[0] = (unsigned char) x;
|
|
p[1] = (unsigned char) (x >> 8);
|
|
p[2] = (unsigned char) (x >> 16);
|
|
p[3] = (unsigned char) (x >> 24);
|
|
p[4] = (unsigned char) (x >> 32);
|
|
p[5] = (unsigned char) (x >> 40);
|
|
p[6] = (unsigned char) (x >> 48);
|
|
p[7] = (unsigned char) (x >> 56);
|
|
}
|
|
|
|
void
|
|
exit_err(const char *msg)
|
|
{
|
|
perror(msg == NULL ? "" : msg);
|
|
exit(2);
|
|
}
|
|
|
|
void
|
|
exit_msg(const char *msg)
|
|
{
|
|
fprintf(stderr, "%s\n", msg);
|
|
exit(2);
|
|
}
|
|
|
|
void *
|
|
xmalloc(size_t size)
|
|
{
|
|
void *pnt;
|
|
|
|
if ((pnt = malloc(size)) == NULL) {
|
|
exit_err("malloc()");
|
|
}
|
|
return pnt;
|
|
}
|
|
|
|
char *
|
|
xstrdup(const char *str)
|
|
{
|
|
char *clone;
|
|
|
|
if ((clone = strdup(str)) == NULL) {
|
|
exit_err("strdup()");
|
|
}
|
|
return clone;
|
|
}
|
|
|
|
void *
|
|
xsodium_malloc(size_t size)
|
|
{
|
|
void *pnt;
|
|
|
|
if ((pnt = sodium_malloc(size)) == NULL) {
|
|
exit_err("sodium_malloc()");
|
|
}
|
|
return pnt;
|
|
}
|
|
|
|
void
|
|
xor_buf(unsigned char *dst, const unsigned char *src, size_t len)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = (size_t) 0U; i < len; i++) {
|
|
dst[i] ^= src[i];
|
|
}
|
|
}
|
|
|
|
int
|
|
xfprintf(FILE *fp, const char *format, ...)
|
|
{
|
|
char *out;
|
|
size_t out_maxlen = 4096U;
|
|
int len;
|
|
va_list va;
|
|
|
|
va_start(va, format);
|
|
out = xsodium_malloc(out_maxlen);
|
|
len = vsnprintf(out, out_maxlen, format, va);
|
|
if (len < 0 || len >= (int) out_maxlen) {
|
|
va_end(va);
|
|
exit_msg("xfprintf() overflow");
|
|
}
|
|
va_end(va);
|
|
if (fwrite(out, (size_t) len, 1U, fp) != 1U) {
|
|
sodium_free(out);
|
|
va_end(va);
|
|
exit_err("fwrite()");
|
|
}
|
|
sodium_free(out);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
xfput_b64(FILE *fp, const unsigned char *bin, size_t bin_len)
|
|
{
|
|
const size_t b64_maxlen = (bin_len + 2) * 4 / 3 + 1;
|
|
char *b64;
|
|
|
|
b64 = xsodium_malloc(b64_maxlen);
|
|
if (bin_to_b64(b64, bin, b64_maxlen, bin_len) == NULL) {
|
|
sodium_free(b64);
|
|
abort();
|
|
}
|
|
xfprintf(fp, "%s\n", b64);
|
|
sodium_free(b64);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
xfclose(FILE *fp)
|
|
{
|
|
if (fp == NULL) {
|
|
abort();
|
|
}
|
|
if (fclose(fp) != 0) {
|
|
exit_err("fclose()");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
trim(char *str)
|
|
{
|
|
size_t i = strlen(str);
|
|
|
|
while (i-- > (size_t) 0U) {
|
|
if (str[i] == '\n' || str[i] == '\r') {
|
|
str[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
const char *
|
|
file_basename(const char *file)
|
|
{
|
|
char *ptr;
|
|
|
|
if ((ptr = strrchr(file, DIR_SEP)) != NULL) {
|
|
return ptr + 1;
|
|
}
|
|
return file;
|
|
}
|
|
|
|
FILE *
|
|
fopen_create_useronly(const char *file)
|
|
{
|
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
|
int fd;
|
|
|
|
if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY,
|
|
(mode_t) 0600)) == -1) {
|
|
return NULL;
|
|
}
|
|
return fdopen(fd, "w");
|
|
#else
|
|
return fopen(file, "w");
|
|
#endif
|
|
}
|
|
|
|
int
|
|
basedir_create_useronly(const char *file)
|
|
{
|
|
const char *basename;
|
|
char *dir;
|
|
int ret = -1;
|
|
|
|
dir = xstrdup(file);
|
|
basename = file_basename(dir);
|
|
if (basename == dir) {
|
|
free(dir);
|
|
return 0;
|
|
}
|
|
dir[basename - dir - 1] = 0;
|
|
|
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
|
if (*dir == 0 || mkdir(dir, 0700) == 0 || errno == EEXIST) {
|
|
ret = 0;
|
|
}
|
|
#elif defined(_WIN32)
|
|
if (*dir == 0 || _mkdir(dir) == 0 || errno == EEXIST) {
|
|
ret = 0;
|
|
}
|
|
#endif
|
|
free(dir);
|
|
return ret;
|
|
}
|
|
|
|
char *get_home_dir(void)
|
|
{
|
|
char *dir;
|
|
#ifdef _WIN32
|
|
const char *hd;
|
|
const char *hp;
|
|
#endif
|
|
|
|
if ((dir = getenv("HOME")) != NULL) {
|
|
return xstrdup(dir);
|
|
}
|
|
#ifdef _WIN32
|
|
if ((dir = getenv("USERPROFILE")) != NULL) {
|
|
return xstrdup(dir);
|
|
}
|
|
if ((dir = getenv("USERPROFILE")) != NULL) {
|
|
return xstrdup(dir);
|
|
}
|
|
if ((hd = getenv("HOMEDRIVE")) != NULL &&
|
|
(hp = getenv("HOMEPATH")) != NULL) {
|
|
if (asprintf(&dir, "%s%s", hd, hp) < 0) {
|
|
exit_err("asprintf()");
|
|
}
|
|
return dir;
|
|
}
|
|
#endif
|
|
return NULL;
|
|
}
|