Browse Source

MT#61977 add S3 auth helpers

Change-Id: I9131556c995d514c2ec2b3eabd9eff4a9e8df23b
pull/1998/head
Richard Fuchs 4 months ago
parent
commit
0b5d094382
2 changed files with 166 additions and 0 deletions
  1. +144
    -0
      lib/s3utils.c
  2. +22
    -0
      lib/s3utils.h

+ 144
- 0
lib/s3utils.c View File

@ -0,0 +1,144 @@
#include "s3utils.h"
#include "log.h"
#include <glib.h>
#include <time.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
static void sha256_digest(unsigned char output[SHA256_DIGEST_LENGTH],
const char *input,
size_t len)
{
const EVP_MD *md = EVP_sha256(); // XXX cache this
// XXX error checking
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, md, NULL);
EVP_DigestUpdate(ctx, input, len);
EVP_DigestFinal_ex(ctx, output, NULL);
EVP_MD_CTX_free(ctx);
}
static void hex_print(char *output,
const unsigned char *buf,
size_t len)
{
for (unsigned int i = 0; i < SHA256_DIGEST_LENGTH; i++)
sprintf(output + i * 2, "%02x", buf[i]);
}
static void hex_append(GString *s,
const unsigned char *buf,
size_t len)
{
size_t pos = s->len;
g_string_set_size(s, s->len + len * 2);
hex_print(s->str + pos, buf, len);
}
void sha256_digest_hex(char output[SHA256_DIGEST_LENGTH * 2 + 1],
const char *input,
size_t len)
{
unsigned char digest[SHA256_DIGEST_LENGTH];
sha256_digest(digest, input, len); // XXX error check?
hex_print(output, digest, SHA256_DIGEST_LENGTH);
}
static void sha256_digest_hex_append(GString *s,
const char *input,
size_t len)
{
printf("sha len %zu\n", len);
unsigned char digest[SHA256_DIGEST_LENGTH];
sha256_digest(digest, input, len); // XXX error check?
hex_append(s, digest, SHA256_DIGEST_LENGTH);
}
GString *s3_make_auth(const char *host,
const char *path, const char *key,
const char *region,
const struct tm *now,
const char *content_sha256_hex,
const char *access_key,
const char *secret_key)
{
// use much larger buffers than necessary to make gcc happy
char date[64];
sprintf(date, "%04d%02d%02d",
now->tm_year + 1900,
now->tm_mon + 1,
now->tm_mday);
char time[64];
sprintf(time, "%02d%02d%02d",
now->tm_hour,
now->tm_min,
now->tm_sec);
g_autoptr(GString) canon_req = g_string_new("PUT\n");
g_string_append(canon_req, path);
g_string_append(canon_req, key);
g_string_append(canon_req, "\n");
g_string_append(canon_req, "\n"); // empty query string
// hard coded list of canonical headers
g_string_append_printf(canon_req, "host:%s\n", host);
g_string_append_printf(canon_req, "x-amz-content-sha256:%s\n", content_sha256_hex);
g_string_append_printf(canon_req, "x-amz-date:%sT%sZ\n",
date, time);
g_string_append(canon_req, "\n");
// signed headers
g_string_append(canon_req, "host;x-amz-content-sha256;x-amz-date\n");
g_string_append(canon_req, content_sha256_hex);
g_autoptr(GString) string_to_sign = g_string_new("AWS4-HMAC-SHA256\n");
g_string_append_printf(string_to_sign, "%sT%sZ\n",
date, time);
g_string_append_printf(string_to_sign, "%s/%s/s3/aws4_request\n",
date, region);
sha256_digest_hex_append(string_to_sign, canon_req->str, canon_req->len);
unsigned char x1[SHA256_DIGEST_LENGTH];
unsigned char x2[SHA256_DIGEST_LENGTH];
unsigned char x3[SHA256_DIGEST_LENGTH];
unsigned char x4[SHA256_DIGEST_LENGTH];
unsigned char x5[SHA256_DIGEST_LENGTH];
g_autoptr(GString) akey = g_string_new("AWS4");
g_string_append(akey, secret_key);
HMAC(EVP_sha256(), akey->str, akey->len,
(unsigned char *) date, strlen(date), x1, NULL);
HMAC(EVP_sha256(), x1, sizeof(x1),
(unsigned char *) region, strlen(region), x2, NULL);
HMAC(EVP_sha256(), x2, sizeof(x2),
(unsigned char *) "s3", strlen("s3"), x3, NULL);
HMAC(EVP_sha256(), x3, sizeof(x3),
(unsigned char *) "aws4_request", strlen("aws4_request"), x4, NULL);
HMAC(EVP_sha256(), x4, sizeof(x4),
(unsigned char *) string_to_sign->str, string_to_sign->len, x5, NULL);
GString *ret = g_string_new("AWS4-HMAC-SHA256 Credential=");
g_string_append(ret, access_key);
g_string_append_c(ret, '/');
g_string_append(ret, date);
g_string_append_c(ret, '/');
g_string_append(ret, region);
g_string_append(ret, "/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;"
"x-amz-date,Signature=");
hex_append(ret, x5, sizeof(x5));
return ret;
}

+ 22
- 0
lib/s3utils.h View File

@ -0,0 +1,22 @@
#ifndef _S3UTILS_H_
#define _S3UTILS_H_
#include <glib.h>
#include <time.h>
#include <openssl/sha.h>
GString *s3_make_auth(const char *host,
const char *path, const char *key,
const char *region,
const struct tm *now,
const char *content_sha256_hex,
const char *access_key,
const char *secret_key);
void sha256_digest_hex(char output[SHA256_DIGEST_LENGTH * 2 + 1],
const char *input,
size_t len);
#endif

Loading…
Cancel
Save