Add Windows support
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
test
|
test
|
||||||
|
test.exe
|
||||||
|
|||||||
@@ -1,2 +1,8 @@
|
|||||||
|
ifeq ($(shell uname -a),Linux)
|
||||||
|
LFLAGS = -lcrypto
|
||||||
|
else
|
||||||
|
LFLAGS = -lbcrypt
|
||||||
|
endif
|
||||||
|
|
||||||
all:
|
all:
|
||||||
cc s3.c test.c -o test -Wall -Wextra -lcrypto -ggdb
|
cc s3.c test.c -o test -Wall -Wextra $(LFLAGS) -ggdb
|
||||||
|
|||||||
@@ -5,8 +5,16 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <bcrypt.h>
|
||||||
|
#ifndef NT_SUCCESS
|
||||||
|
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/params.h>
|
#include <openssl/params.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "s3.h"
|
#include "s3.h"
|
||||||
|
|
||||||
@@ -59,7 +67,6 @@ static int inplace_hex(char *buf, int len, bool up)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: double check this function
|
|
||||||
static bool needs_percent(char c)
|
static bool needs_percent(char c)
|
||||||
{
|
{
|
||||||
if ((c >= 'a' && c <= 'z') ||
|
if ((c >= 'a' && c <= 'z') ||
|
||||||
@@ -121,6 +128,37 @@ static int sha256_len(char *buf, int len)
|
|||||||
// src and dst may overlap
|
// src and dst may overlap
|
||||||
static int sha256(char *src, int len, char *dst)
|
static int sha256(char *src, int len, char *dst)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
BCRYPT_ALG_HANDLE alg = NULL;
|
||||||
|
NTSTATUS status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, NULL, 0);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
BCRYPT_HASH_HANDLE hash = NULL;
|
||||||
|
status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BCryptHashData(hash, (PUCHAR) src, (ULONG) len, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BCryptFinishHash(hash, (PUCHAR) dst, 32, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
int olen = sha256_len(src, len);
|
int olen = sha256_len(src, len);
|
||||||
|
|
||||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||||
@@ -149,6 +187,7 @@ static int sha256(char *src, int len, char *dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EVP_MD_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,11 +206,41 @@ static int hmac_len(char *buf, int len1, int len2)
|
|||||||
|
|
||||||
static int inplace_hmac(char *buf, int len1, int len2)
|
static int inplace_hmac(char *buf, int len1, int len2)
|
||||||
{
|
{
|
||||||
int olen = hmac_len(buf, len1, len2);
|
|
||||||
|
|
||||||
S3_String key = { buf, len1 };
|
S3_String key = { buf, len1 };
|
||||||
S3_String data = { buf + len1, len2 };
|
S3_String data = { buf + len1, len2 };
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
BCRYPT_ALG_HANDLE alg = NULL;
|
||||||
|
NTSTATUS status = BCryptOpenAlgorithmProvider(&alg,
|
||||||
|
BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
BCRYPT_HASH_HANDLE hash = NULL;
|
||||||
|
status = BCryptCreateHash(alg, &hash, NULL, 0, (PUCHAR) key.ptr, (ULONG) key.len, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BCryptHashData(hash, (PUCHAR) data.ptr, (ULONG) data.len, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BCryptFinishHash(hash, (PUCHAR) buf, 32, 0);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BCryptDestroyHash(hash);
|
||||||
|
BCryptCloseAlgorithmProvider(alg, 0);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||||
if (mac == NULL) {
|
if (mac == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -213,7 +282,8 @@ static int inplace_hmac(char *buf, int len1, int len2)
|
|||||||
|
|
||||||
EVP_MAC_CTX_free(ctx);
|
EVP_MAC_CTX_free(ctx);
|
||||||
EVP_MAC_free(mac);
|
EVP_MAC_free(mac);
|
||||||
return olen;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
@@ -371,7 +441,7 @@ static void pop_mod_(Builder *b, char *file, int line)
|
|||||||
ret = inplace_hex(
|
ret = inplace_hex(
|
||||||
b->dst + mod.off_0,
|
b->dst + mod.off_0,
|
||||||
b->len - mod.off_0,
|
b->len - mod.off_0,
|
||||||
true);
|
false);
|
||||||
break;
|
break;
|
||||||
case MOD_PCT:
|
case MOD_PCT:
|
||||||
ret = inplace_pct(
|
ret = inplace_pct(
|
||||||
@@ -422,8 +492,10 @@ static void append_credential(Builder *b,
|
|||||||
S3_String access_key, S3_String yyyymmdd,
|
S3_String access_key, S3_String yyyymmdd,
|
||||||
S3_String region, S3_String service)
|
S3_String region, S3_String service)
|
||||||
{
|
{
|
||||||
append(b, access_key);
|
if (access_key.len > 0) {
|
||||||
append(b, S3_S("/"));
|
append(b, access_key);
|
||||||
|
append(b, S3_S("/"));
|
||||||
|
}
|
||||||
append(b, yyyymmdd);
|
append(b, yyyymmdd);
|
||||||
append(b, S3_S("/"));
|
append(b, S3_S("/"));
|
||||||
append(b, region);
|
append(b, region);
|
||||||
@@ -435,7 +507,7 @@ static void append_credential(Builder *b,
|
|||||||
static int unpack_time(time_t time, struct tm *out)
|
static int unpack_time(time_t time, struct tm *out)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (gmtime_s(out, time) != 0)
|
if (gmtime_s(out, &time) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
@@ -549,6 +621,11 @@ int s3_presign_url(
|
|||||||
append(&b, S3_S("aws4_request"));
|
append(&b, S3_S("aws4_request"));
|
||||||
pop_mod(&b);
|
pop_mod(&b);
|
||||||
flush(&b);
|
flush(&b);
|
||||||
|
append(&b, S3_S("AWS4-HMAC-SHA256\n"));
|
||||||
|
append(&b, yyyymmddthhmmssz);
|
||||||
|
append(&b, S3_S("\n"));
|
||||||
|
append_credential(&b, S3_S(""), yyyymmdd, region, service);
|
||||||
|
append(&b, S3_S("\n"));
|
||||||
push_mod(&b, MOD_HEX);
|
push_mod(&b, MOD_HEX);
|
||||||
push_mod(&b, MOD_SHA256);
|
push_mod(&b, MOD_SHA256);
|
||||||
append(&b, method);
|
append(&b, method);
|
||||||
|
|||||||
Reference in New Issue
Block a user