aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/libeclat.h18
-rw-r--r--lib/reqsign.c97
3 files changed, 116 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 522a5bf..1162210 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -20,6 +20,7 @@ libeclat_a_SOURCES=\
base64.c\
hmac_sha1.c\
libeclat.h\
+ reqsign.c\
sha1.c\
sha1.h\
urlencode.c
diff --git a/lib/libeclat.h b/lib/libeclat.h
index 0c6006e..1212dc4 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -27,3 +27,21 @@ void eclat_base64_encode(const unsigned char *input, size_t input_len,
int eclat_base64_decode(const unsigned char *input, size_t input_len,
unsigned char **output, size_t *output_len);
+
+struct ec2_param {
+ char *name;
+ char *value;
+};
+
+struct ec2_query {
+ int https;
+ char *endpoint; /* endpoint */
+ char *uri; /* URI without parameters */
+ char *verb; /* GET or POST */
+ struct grecs_symtab *params; /* Query parameters */
+};
+
+int eclat_query_signature(struct ec2_query *req, char *secret,
+ char **signature);
+
+
diff --git a/lib/reqsign.c b/lib/reqsign.c
new file mode 100644
index 0000000..bc65efe
--- /dev/null
+++ b/lib/reqsign.c
@@ -0,0 +1,97 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012 Sergey Poznyakoff.
+
+ Eclat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Eclat is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Eclat. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <string.h>
+#include "libeclat.h"
+#include "grecs.h"
+
+struct pname {
+ size_t i;
+ char **a;
+};
+
+static int
+get_param_name(void *sym, void *data)
+{
+ struct grecs_syment *se = sym;
+ struct pname *pn = data;
+ pn->a[pn->i++] = se->name;
+ return 0;
+}
+
+static int
+compnames(const void *a, const void *b)
+{
+ char * const *ac = a;
+ char * const *bc = b;
+ return strcmp(*ac, *bc);
+}
+
+int
+eclat_query_signature(struct ec2_query *req, char *secret,
+ char **signature)
+{
+ char **pnames;
+ size_t i, n;
+ struct grecs_txtacc *acc;
+ struct pname pn;
+ char *str;
+ char digest[20];
+ size_t siglen;
+
+ acc = grecs_txtacc_create();
+
+ /* Collect and sort parameter names */
+ n = grecs_symtab_count_entries(req->params);
+ pnames = grecs_calloc(n, sizeof(pnames[0]));
+ pn.i = 0;
+ pn.a = pnames;
+ grecs_symtab_enumerate(req->params, get_param_name, &pn);
+ qsort(pnames, n, sizeof(pnames[0]), compnames);
+
+ grecs_txtacc_grow(acc, req->verb, strlen(req->verb));
+ grecs_txtacc_grow_char(acc, '\n');
+ grecs_txtacc_grow(acc, req->endpoint, strlen(req->endpoint));
+ grecs_txtacc_grow_char(acc, '\n');
+ grecs_txtacc_grow(acc, req->uri, strlen(req->uri));
+ grecs_txtacc_grow_char(acc, '\n');
+
+ /* Append a canonicalized query string */
+ for (i = 0; i < n; i++) {
+ struct ec2_param *p =
+ grecs_symtab_lookup_or_install(req->params, pnames[i],
+ NULL);
+ if (!p)
+ abort();
+ if (i != 0)
+ grecs_txtacc_grow_char(acc, '&');
+ grecs_txtacc_grow(acc, p->name, strlen(p->name));
+ grecs_txtacc_grow_char(acc, '=');
+ if (p->value)
+ grecs_txtacc_grow(acc, p->value, strlen(p->value));
+ }
+ grecs_txtacc_grow_char(acc, 0);
+ str = grecs_txtacc_finish(acc, 0);
+
+ hmac_sha1(str, strlen(str), secret, strlen(secret), digest);
+
+ eclat_base64_encode(digest, sizeof(digest),
+ (unsigned char**) signature, &siglen);
+
+ grecs_txtacc_free(acc);
+ free(pnames);
+}

Return to:

Send suggestions and report system problems to the System administrator.