-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsigv4.h
More file actions
171 lines (141 loc) · 5.59 KB
/
sigv4.h
File metadata and controls
171 lines (141 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#ifndef __AWS_SIGV4_H
#define __AWS_SIGV4_H
/*
Replace the standards header files with a single system-specific header file.
Value must include quotes, for example `#define SIGV4_SYSTEM_HEADER "foo.h"
*/
#ifdef SIGV4_SYSTEM_HEADER
#include SIGV4_SYSTEM_HEADER
#else
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#endif
#define AWS_SIGV4_BUFFER_OVERFLOW_ERROR -2
#define AWS_SIGV4_INVALID_INPUT_ERROR -1
#define AWS_SIGV4_OK 0
#define AWS_SIGV4_MAX_NUM_HEADERS 10
#define AWS_SIGV4_AUTH_HEADER_MAX_LEN 2048
typedef struct aws_sigv4_str_s
{
unsigned char *data;
unsigned int len;
} aws_sigv4_str_t;
typedef struct aws_sigv4_kv_s
{
aws_sigv4_str_t key;
aws_sigv4_str_t value;
} aws_sigv4_kv_t;
aws_sigv4_str_t aws_sigv4_string(const unsigned char *cstr);
int aws_sigv4_strcmp(aws_sigv4_str_t *str1, aws_sigv4_str_t *str2);
int aws_sigv4_empty_str(aws_sigv4_str_t *str);
unsigned char *aws_sigv4_sprintf(unsigned char *buf, const char *fmt, ...);
unsigned char *aws_sigv4_snprintf(unsigned char *buf, unsigned int n, const char *fmt, ...);
typedef aws_sigv4_kv_t aws_sigv4_header_t;
typedef int (*aws_sigv4_compare_func_t)(const void *, const void *);
typedef struct aws_sigv4_params_s
{
/* AWS credential parameters */
aws_sigv4_str_t secret_access_key;
aws_sigv4_str_t access_key_id;
/* HTTP request parameters */
aws_sigv4_str_t method;
aws_sigv4_str_t uri;
aws_sigv4_str_t query_str;
aws_sigv4_str_t host;
/* x-amz-date header value in ISO8601 format */
aws_sigv4_str_t x_amz_date;
aws_sigv4_str_t payload;
/* if true, use UNSIGNED-PAYLOAD for x-amz-content-sha256 */
bool unsigned_payload;
/* AWS service parameters */
aws_sigv4_str_t service;
aws_sigv4_str_t region;
/* Additional headers */
aws_sigv4_kv_t headers[AWS_SIGV4_MAX_NUM_HEADERS];
unsigned int num_headers;
/* Sorting function */
void (*sort)(void *base, size_t n, size_t size,
aws_sigv4_compare_func_t cmp);
/* SHA256 function */
void (*sha256)(const unsigned char *data, unsigned int len, unsigned char *out);
/* HMAC SHA256 function */
int (*hmac_sha256)(const unsigned char *data, size_t data_len,
const unsigned char *key, size_t key_len,
unsigned char *out, size_t *out_len);
} aws_sigv4_params_t;
/** @brief get hex encoding of a given string
*
* @param[in] str_in Input string
* @param[out] hex_out Output buffer to store hex encoded string
*/
void get_hexdigest(aws_sigv4_str_t *str_in,
aws_sigv4_str_t *hex_out);
/** @brief get hex encoded sha256 of a given string
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[in] str_in Input string
* @param[out] hex_sha256_out Output buffer to store hex encoded sha256 string
*/
void get_hex_sha256(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *str_in,
aws_sigv4_str_t *hex_sha256_out);
/** @brief derive signing key
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[out] signing_key Struct of buffer to store derived signing key
*/
void get_signing_key(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *signing_key);
/** @brief get credential scope string
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[out] credential_scope Struct of buffer to store credential scope string
*/
void get_credential_scope(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *credential_scope);
/** @brief get signed headers string
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[out] signed_headers Struct of buffer to store signed headers string
*/
void get_signed_headers(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *signed_headers);
/** @brief get canonical headers string
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[out] canonical_headers Struct of buffer to store canonical headers string
*/
void get_canonical_headers(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *canonical_headers);
/** @brief get canonical request string
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[out] canonical_request Struct of buffer to store canonical request string
*/
int get_canonical_request(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *canonical_request);
/** @brief get string to sign
*
* @param[in] sigv4_params Pointer to a struct of sigv4 parameters
* @param[in] request_date A pointer to a struct of request date in ISO8601 format
* @param[in] credential_scope Pointer to a struct of precomputed credential scope
* @param[in] canonical_request Pointer to a struct of precomputed canonical request
* @param[out] string_to_sign Struct of buffer to store string to sign
*/
void get_string_to_sign(aws_sigv4_params_t *sigv4_params,
aws_sigv4_str_t *request_date,
aws_sigv4_str_t *credential_scope,
aws_sigv4_str_t *canonical_request,
aws_sigv4_str_t *string_to_sign);
/** @brief perform sigv4 signing
*
* @param[in] sigv4_params A pointer to a struct of sigv4 parameters
* @param[out] auth_header A struct to store Authorization header name and value
* @return Status code where zero for success and non-zero for failure
*/
int aws_sigv4_sign(aws_sigv4_params_t *sigv4_params, aws_sigv4_header_t *auth_header);
#endif /* __AWS_SIGV4_H */