Fixed compatibility for HTTPClient Library. (HTTPClient by Donatien Garnier)
Dependents: FlashAir_Twitter CyaSSL-Twitter-OAuth4Tw TweetTest NetworkThermometer ... more
Fork of OAuth4Tw by
Revision 3:c28b796ef7ed, committed 2015-07-08
- Comitter:
- ban4jp
- Date:
- Wed Jul 08 03:52:54 2015 +0000
- Parent:
- 2:a057c813fb02
- Child:
- 4:1ecf49a46040
- Commit message:
- Change the folder structure.; Updated code from twicpps. (just a little.)
Changed in this revision
--- a/OAuth4Tw.cpp Mon Dec 15 12:24:37 2014 +0000
+++ b/OAuth4Tw.cpp Wed Jul 08 03:52:54 2015 +0000
@@ -1,6 +1,11 @@
#include "OAuth4Tw.h"
#include "mbed.h"
-#include "oauth.h"
+#include "twicpps/oauth.h"
+
+#include <HTTPClient.h>
+#include "HTTPPostText.h"
+
+static char res_buffer[1024] = "";
OAuth4Tw::OAuth4Tw(const char *c_key, const char *c_secret,
const char *t_key, const char *t_secret)
@@ -16,12 +21,18 @@
std::string OAuth4Tw::post(const char *uri, std::string postarg) {
std::string req_url;
- std::string postres;
req_url = oauth_sign_url2(uri, &postarg, OA_HMAC, 0,
consumer_key, consumer_secret, token_key, token_secret);
- postres = oauth_http_post(req_url.c_str(), postarg.c_str());
- return postres;
+ const char *u = req_url.c_str();
+ const char *p = postarg.c_str();
+
+ HTTPClient http;
+ HTTPPostText req((char *)p, strlen(p) + 1);
+ HTTPText res(res_buffer, sizeof(res_buffer));
+ http.post(u, req, &res);
+
+ return res_buffer;
}
--- a/OAuth4Tw.h Mon Dec 15 12:24:37 2014 +0000
+++ b/OAuth4Tw.h Wed Jul 08 03:52:54 2015 +0000
@@ -2,7 +2,7 @@
#define MBED_OAUTH4TW_H
#include "mbed.h"
-#include "oauth.h"
+#include <string>
class OAuth4Tw {
public:
--- a/hash.cpp Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-
-#include "oauth.h" // base64 encode fn's.
-#include "sha1.h"
-
-#include <string.h>
-
-void hmac_sha1(unsigned char const *key, size_t keylen, unsigned char const *in, size_t inlen, unsigned char *resbuf)
-{
- struct SHA1Context inner;
- struct SHA1Context outer;
- unsigned char tmpkey[20];
- unsigned char digest[20];
- unsigned char block[64];
-
- const int IPAD = 0x36;
- const int OPAD = 0x5c;
-
- if (keylen > 64) {
- struct SHA1Context keyhash;
- SHA1Reset(&keyhash);
- SHA1Input(&keyhash, key, keylen);
- SHA1Result(&keyhash, tmpkey);
- key = tmpkey;
- keylen = 20;
- }
-
- for (size_t i = 0; i < sizeof(block); i++) {
- block[i] = IPAD ^ (i < keylen ? key[i] : 0);
- }
- SHA1Reset(&inner);
- SHA1Input(&inner, block, 64);
- SHA1Input(&inner, in, inlen);
- SHA1Result(&inner, digest);
-
- for (size_t i = 0; i < sizeof(block); i++) {
- block[i] = OPAD ^ (i < keylen ? key[i] : 0);
- }
- SHA1Reset(&outer);
- SHA1Input(&outer, block, 64);
- SHA1Input(&outer, digest, 20);
- SHA1Result(&outer, resbuf);
-}
-
-
-std::string oauth_sign_hmac_sha1(const char *m, const char *k)
-{
- return oauth_sign_hmac_sha1_raw(m, strlen(m), k, strlen(k));
-}
-
-std::string oauth_sign_hmac_sha1_raw(const char *m, const size_t ml, const char *k, const size_t kl)
-{
- unsigned char result[20];
- hmac_sha1((unsigned char const *)k, kl, (unsigned char const *)m, ml, result);
- return oauth_encode_base64(result, 20);
-}
-
--- a/oauth.cpp Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,719 +0,0 @@
-/*
- * OAuth string functions in POSIX-C.
- *
- * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
- *
- * The base64 functions are by Jan-Henrik Haukeland, <hauk@tildeslash.com>
- * and un/escape_url() was inspired by libcurl's curl_escape under ISC-license
- * many thanks to Daniel Stenberg <daniel@haxx.se>.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define WIPE_MEMORY ///< overwrite sensitve data before free()ing it.
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <math.h>
-#include <ctype.h> // isxdigit
-
-#include "oauth.h"
-
-#include <vector>
-#include <algorithm>
-#include <sstream>
-
-/**
- * Base64 encode one byte
- */
-char oauth_b64_encode(unsigned char u)
-{
- if (u < 26) return 'A' + u;
- if (u < 52) return 'a' + (u - 26);
- if (u < 62) return '0' + (u - 52);
- if (u == 62) return '+';
- return '/';
-}
-
-/**
- * Decode a single base64 character.
- */
-unsigned char oauth_b64_decode(char c)
-{
- if (c >= 'A' && c <= 'Z') return(c - 'A');
- if (c >= 'a' && c <= 'z') return(c - 'a' + 26);
- if (c >= '0' && c <= '9') return(c - '0' + 52);
- if (c == '+') return 62;
- return 63;
-}
-
-/**
- * Return TRUE if 'c' is a valid base64 character, otherwise FALSE
- */
-bool oauth_b64_is_base64(char c)
-{
- return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/') || (c == '='));
-}
-
-/**
- * Base64 encode and return size data in 'src'. The caller must free the
- * returned string.
- *
- * @param size The size of the data in src
- * @param src The data to be base64 encode
- * @return encoded string otherwise NULL
- */
-std::string oauth_encode_base64(const unsigned char *src, int size)
-{
- int i;
- std::stringbuf sb;
-
- if (!src) return NULL;
- if (!size) size= strlen((char *)src);
-
- for (i = 0; i < size; i += 3) {
- unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0;
- b1= src[i];
- if (i + 1 < size) b2 = src[i + 1];
- if (i + 2 < size) b3 = src[i + 2];
-
- b4= b1 >> 2;
- b5= ((b1 & 0x3) << 4) | (b2 >> 4);
- b6= ((b2 & 0xf) << 2) | (b3 >> 6);
- b7= b3 & 0x3f;
-
- sb.sputc(oauth_b64_encode(b4));
- sb.sputc(oauth_b64_encode(b5));
-
- if (i + 1 < size) {
- sb.sputc(oauth_b64_encode(b6));
- } else {
- sb.sputc('=');
- }
-
- if (i + 2 < size) {
- sb.sputc(oauth_b64_encode(b7));
- } else {
- sb.sputc('=');
- }
- }
- return sb.str();
-}
-
-/**
- * Decode the base64 encoded string 'src' into the memory pointed to by
- * 'dest'.
- *
- * @param dest Pointer to memory for holding the decoded string.
- * Must be large enough to receive the decoded string.
- * @param src A base64 encoded string.
- * @return the length of the decoded string if decode
- * succeeded otherwise 0.
- */
-std::string oauth_decode_base64(const char *src)
-{
- if (src && *src) {
- std::stringbuf sb;
- //unsigned char *p= dest;
- int k, l= strlen(src)+1;
- std::vector<unsigned char> buf(l);
-
- /* Ignore non base64 chars as per the POSIX standard */
- for (k = 0, l = 0; src[k]; k++) {
- if (oauth_b64_is_base64(src[k])) {
- buf[l++]= src[k];
- }
- }
-
- for (k = 0; k < l; k += 4) {
- char c1='A', c2='A', c3='A', c4='A';
- unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0;
- c1= buf[k];
-
- if (k + 1 < l) c2 = buf[k + 1];
- if (k + 2 < l) c3 = buf[k + 2];
- if (k + 3 < l) c4 = buf[k + 3];
-
- b1 = oauth_b64_decode(c1);
- b2 = oauth_b64_decode(c2);
- b3 = oauth_b64_decode(c3);
- b4 = oauth_b64_decode(c4);
-
- sb.sputc((b1 << 2) | (b2 >> 4));
-
- if (c3 != '=') sb.sputc(((b2 & 0xf) << 4) | (b3 >> 2));
- if (c4 != '=') sb.sputc(((b3 & 0x3) << 6) | b4);
- }
-
- return sb.str();
- }
- return 0;
-}
-
-/**
- * Escape 'string' according to RFC3986 and
- * http://oauth.net/core/1.0/#encoding_parameters.
- *
- * @param string The data to be encoded
- * @return encoded string otherwise NULL
- * The caller must free the returned string.
- */
-std::string oauth_url_escape(const char *string)
-{
- unsigned char in;
- size_t length;
-
- if (!string) {
- return std::string();
- }
-
- length = strlen(string);
-
- std::stringbuf sb;
-
- while (length--) {
- in = *string;
- if (strchr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_~.-", in)) {
- sb.sputc(in);
- } else {
- char tmp[10];
- snprintf(tmp, 4, "%%%02X", in);
- sb.sputc(tmp[0]);
- sb.sputc(tmp[1]);
- sb.sputc(tmp[2]);
- }
- string++;
- }
- return sb.str();
-}
-
-#ifndef ISXDIGIT
-# define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
-#endif
-
-/**
- * Parse RFC3986 encoded 'string' back to unescaped version.
- *
- * @param string The data to be unescaped
- * @param olen unless NULL the length of the returned string is stored there.
- * @return decoded string or NULL
- * The caller must free the returned string.
- */
-std::string oauth_url_unescape(const char *string)
-{
- size_t alloc, strindex=0;
- unsigned char in;
- long hex;
-
- if (!string) return NULL;
-
- alloc = strlen(string)+1;
- std::vector<char> ns(alloc);
-
- while(--alloc > 0) {
- in = *string;
- if (('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
- char hexstr[3]; // '%XX'
- hexstr[0] = string[1];
- hexstr[1] = string[2];
- hexstr[2] = 0;
- hex = strtol(hexstr, NULL, 16);
- in = (unsigned char)hex; /* hex is always < 256 */
- string += 2;
- alloc -= 2;
- }
- ns[strindex++] = in;
- string++;
- }
- ns[strindex]=0;
- return &ns[0];
-}
-
-/**
- * returns plaintext signature for the given key.
- *
- * the returned string needs to be freed by the caller
- *
- * @param m message to be signed
- * @param k key used for signing
- * @return signature string
- */
-std::string oauth_sign_plaintext (const char *m, const char *k)
-{
- return oauth_url_escape(k);
-}
-
-/**
- * encode strings and concatenate with '&' separator.
- * The number of strings to be concatenated must be
- * given as first argument.
- * all arguments thereafter must be of type (char *)
- *
- * @param len the number of arguments to follow this parameter
- * @param ... string to escape and added (may be NULL)
- *
- * @return pointer to memory holding the concatenated
- * strings - needs to be free(d) by the caller. or NULL
- * in case we ran out of memory.
- */
-std::string oauth_catenc(int len, ...)
-{
- va_list va;
- std::string str;
- va_start(va, len);
- for (int i = 0; i < len; i++) {
- char *arg = va_arg(va, char *);
- std::string enc = oauth_url_escape(arg);
- if (i > 0) str += "&";
- str += enc;
- }
- va_end(va);
- return str;
-}
-
-/**
- * splits the given url into a parameter array.
- * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
- *
- * NOTE: Request-parameters-values may include an ampersand character.
- * However if unescaped this function will use them as parameter delimiter.
- * If you need to make such a request, this function since version 0.3.5 allows
- * to use the ASCII SOH (0x01) character as alias for '&' (0x26).
- * (the motivation is convenience: SOH is /untypeable/ and much more
- * unlikely to appear than '&' - If you plan to sign fancy URLs you
- * should not split a query-string, but rather provide the parameter array
- * directly to \ref oauth_serialize_url)
- *
- * @param url the url or query-string to parse.
- * @param argv pointer to a (char *) array where the results are stored.
- * The array is re-allocated to match the number of parameters and each
- * parameter-string is allocated with strdup. - The memory needs to be freed
- * by the caller.
- * @param qesc use query parameter escape (vs post-param-escape) - if set
- * to 1 all '+' are treated as spaces ' '
- *
- * @return number of parameter(s) in array.
- */
-void oauth_split_post_paramters(const char *url, std::vector<std::string> *argv, short qesc)
-{
- int argc=0;
- char *token, *tmp;
- if (!argv) return;
- if (!url) return;
- std::vector<char> t1(strlen(url) + 1);
- strcpy(&t1[0], url);
-
- // '+' represents a space, in a URL query string
- while ((qesc&1) && (tmp = strchr(&t1[0],'+'))) *tmp = ' ';
-
- tmp = &t1[0];
- while ((token = strtok(tmp,"&?"))) {
- if (!strncasecmp("oauth_signature=", token, 16)) continue;
- while (!(qesc & 2) && (tmp = strchr(token, '\001'))) *tmp = '&';
- argv->push_back(oauth_url_unescape(token));
- if (argc == 0 && strstr(token, ":/")) {
- // HTTP does not allow empty absolute paths, so the URL
- // 'http://example.com' is equivalent to 'http://example.com/' and should
- // be treated as such for the purposes of OAuth signing (rfc2616, section 3.2.1)
- // see http://groups.google.com/group/oauth/browse_thread/thread/c44b6f061bfd98c?hl=en
- char *slash = strstr(token, ":/");
- while (slash && *(++slash) == '/') ; // skip slashes eg /xxx:[\/]*/
-#if 0
- // skip possibly unescaped slashes in the userinfo - they're not allowed by RFC2396 but have been seen.
- // the hostname/IP may only contain alphanumeric characters - so we're safe there.
- if (slash && strchr(slash,'@')) slash=strchr(slash, '@');
-#endif
- if (slash && !strchr(slash,'/')) {
-#ifdef DEBUG_OAUTH
- fprintf(stderr, "\nliboauth: added trailing slash to URL: '%s'\n\n", token);
-#endif
- argv->push_back(std::string(token) + "/");
- }
- }
- if (argc == 0 && (tmp = strstr((char *)argv->at(argc).c_str(), ":80/"))) {
- memmove(tmp, tmp + 3, strlen(tmp + 2));
- }
- tmp = NULL;
- argc++;
- }
-}
-
-void oauth_split_url_parameters(const char *url, std::vector<std::string> *argv)
-{
- oauth_split_post_paramters(url, argv, 1);
-}
-
-/**
- * build a url query string from an array.
- *
- * @param argc the total number of elements in the array
- * @param start element in the array at which to start concatenating.
- * @param argv parameter-array to concatenate.
- * @return url string needs to be freed by the caller.
- *
- */
-std::string oauth_serialize_url (std::vector<std::string> const &argv, int start)
-{
- return oauth_serialize_url_sep(argv, start, "&", 0);
-}
-
-/**
- * encode query parameters from an array.
- *
- * @param argc the total number of elements in the array
- * @param start element in the array at which to start concatenating.
- * @param argv parameter-array to concatenate.
- * @param sep separator for parameters (usually "&")
- * @param mod - bitwise modifiers:
- * 1: skip all values that start with "oauth_"
- * 2: skip all values that don't start with "oauth_"
- * 4: add double quotation marks around values (use with sep=", " to generate HTTP Authorization header).
- * @return url string needs to be freed by the caller.
- */
-std::string oauth_serialize_url_sep(std::vector<std::string> const &argv, int start, char const *sep, int mod)
-{
- int i;
- int first = 0;
- int seplen = strlen(sep);
- std::string query;
- for (i = start; i < (int)argv.size(); i++) {
- std::string tmp;
-
- if ((mod & 1) == 1 && (strncmp(argv[i].c_str(), "oauth_", 6) == 0 || strncmp(argv[i].c_str(), "x_oauth_", 8) == 0)) continue;
- if ((mod & 2) == 2 && (strncmp(argv[i].c_str(), "oauth_", 6) != 0 && strncmp(argv[i].c_str(), "x_oauth_", 8) != 0) && i != 0) continue;
-
- if (i == start && i == 0 && strstr(argv[i].c_str(), ":/")) {
- tmp = argv[i];
- } else {
- char *p = strchr((char *)argv[i].c_str(), '=');
- if (p) {
- tmp = oauth_url_escape(std::string(argv[i].c_str(), (char const *)p).c_str());
- std::string t2 = oauth_url_escape(p + 1);
- tmp += "=";
- if (mod & 4) tmp += "\"";
- tmp += t2;
- if (mod & 4) tmp += "\"";
- } else {
- // see http://oauth.net/core/1.0/#anchor14
- // escape parameter names and arguments but not the '='
- tmp=argv[i];
- tmp += "=";
- }
- }
- query += ((i == start || first) ? "" : sep);
- query += tmp;
- first = 0;
- if (i == start && i == 0 && strstr((char *)tmp.c_str(), ":/")) {
- query += "?";
- first = 1;
- }
- }
- return (query);
-}
-
-/**
- * build a query parameter string from an array.
- *
- * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv).
- * It strips the leading host/path, which is usually the first
- * element when using oauth_split_url_parameters on an URL.
- *
- * @param argc the total number of elements in the array
- * @param argv parameter-array to concatenate.
- * @return url string needs to be freed by the caller.
- */
-std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv)
-{
- return oauth_serialize_url(argv, 1);
-}
-
-/**
- * generate a random string between 15 and 32 chars length
- * and return a pointer to it. The value needs to be freed by the
- * caller
- *
- * @return zero terminated random string.
- */
-std::string oauth_gen_nonce()
-{
- static const char *chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
- const unsigned int max = 26 + 26 + 10 + 1; //strlen(chars);
- char tmp[50];
- int i, len;
-
- srand((unsigned int)time(0));
- len = 15 + rand() % 16;
- for (i = 0; i < len; i++) {
- tmp[i] = chars[rand() % max];
- }
- tmp[i]='\0';
- return &tmp[0];
-}
-
-/**
- * string compare function for oauth parameters.
- *
- * used with qsort. needed to normalize request parameters.
- * see http://oauth.net/core/1.0/#anchor14
- */
-int oauth_cmpstringp(const void *p1, const void *p2)
-{
- char const *e1;
- char const *e2;
- e1 = strchr((char *)p1, '=');
- e2 = strchr((char *)p2, '=');
- if (e1 && e2) {
- std::string left((char const *)p1, e1);
- std::string right((char const *)p2, e2);
- return strcmp(left.c_str(), right.c_str());
- }
-
- std::string left = oauth_url_escape((char const *)p1);
- std::string right = oauth_url_escape((char const *)p2);
- return strcmp(left.c_str(), right.c_str());
-}
-
-bool oauth_cmpstringp_ex(std::string const &left, std::string const &right)
-{
- return oauth_cmpstringp(left.c_str(), right.c_str()) < 0;
-}
-
-/**
- * search array for parameter key.
- * @param argv length of array to search
- * @param argc parameter array to search
- * @param key key of parameter to check.
- *
- * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise.
- */
-bool oauth_param_exists(std::vector<std::string> const &argv, char const *key)
-{
- int i;
- size_t l = strlen(key);
- for (i = 0; i < (int)argv.size(); i++) {
- if (!strncmp(argv[i].c_str(), key, l) && argv[i][l] == '=') {
- return true;
- }
- }
- return false;
-}
-
-/**
- *
- */
-void oauth_add_protocol(
- std::vector<std::string> *argvp,
- OAuthMethod method,
- const char *c_key, //< consumer key - posted plain text
- const char *t_key //< token key - posted plain text in URL
-)
-{
- char oarg[1024];
-
- // add OAuth specific arguments
- if (!oauth_param_exists(*argvp,"oauth_nonce")) {
- std::string tmp = oauth_gen_nonce();
- snprintf(oarg, 1024, "oauth_nonce=%s", tmp.c_str());
- argvp->push_back(oarg);
- }
-
- if (!oauth_param_exists(*argvp,"oauth_timestamp")) {
- long t = time(0);
- snprintf(oarg, 1024, "oauth_timestamp=%u", t);
- argvp->push_back(oarg);
- }
-
- if (t_key) {
- snprintf(oarg, 1024, "oauth_token=%s", t_key);
- argvp->push_back(oarg);
- }
-
- snprintf(oarg, 1024, "oauth_consumer_key=%s", c_key);
- argvp->push_back(oarg);
-
- snprintf(oarg, 1024, "oauth_signature_method=%s", method==0?"HMAC-SHA1":method==1?"RSA-SHA1":"PLAINTEXT");
- argvp->push_back(oarg);
-
- if (!oauth_param_exists(*argvp,"oauth_version")) {
- snprintf(oarg, 1024, "oauth_version=1.0");
- argvp->push_back(oarg);
- }
-
-#if 0 // oauth_version 1.0 Rev A
- if (!oauth_param_exists(argv,argc,"oauth_callback")) {
- snprintf(oarg, 1024, "oauth_callback=oob");
- argvp->push_back(oarg);
- }
-#endif
-
-}
-
-std::string oauth_sign_url(
- const char *url,
- std::string *postargs,
- OAuthMethod method,
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
-)
-{
- return oauth_sign_url2(url, postargs, method, NULL, c_key, c_secret, t_key, t_secret);
-}
-
-std::string oauth_sign_url2(
- const char *url,
- std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
-)
-{
- //char **argv = NULL;
- std::vector<std::string> argv;
- std::string rv;
-
- if (postargs) {
- oauth_split_post_paramters(url, &argv, 0);
- } else {
- oauth_split_url_parameters(url, &argv);
- }
-
- rv = oauth_sign_array2(&argv, postargs, method, http_method, c_key, c_secret, t_key, t_secret);
-
- return(rv);
-}
-
-std::string oauth_sign_array(
- std::vector<std::string> *argvp,
- std::string *postargs,
- OAuthMethod method,
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
-)
-{
- return oauth_sign_array2(
- argvp,
- postargs, method,
- NULL,
- c_key, c_secret,
- t_key, t_secret
- );
-}
-
-void oauth_sign_array2_process(
- std::vector<std::string> *argvp,
- std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
-)
-{
- char oarg[1024];
- std::string query;
- std::string sign;
- std::string http_request_method;
-
- if (!http_method) {
- http_request_method = postargs ? "POST" : "GET";
- } else {
- std::vector<char> tmp(strlen(http_method) + 1);
- int i;
- for (i = 0; http_method[i]; i++) {
- tmp[i] = toupper(http_method[i]);
- }
- tmp[i] = 0;
- http_request_method = &tmp[0];
- }
-
- // add required OAuth protocol parameters
- oauth_add_protocol(argvp, method, c_key, t_key);
-
- // sort parameters
- //qsort(&(*argvp)[1], (*argcp)-1, sizeof(char *), oauth_cmpstringp);
- std::sort(argvp->begin() + 1, argvp->end(), oauth_cmpstringp_ex);
-
- // serialize URL - base-url
- query= oauth_serialize_url_parameters(*argvp);
-
- // generate signature
- std::string okey = oauth_catenc(2, c_secret, t_secret);
- std::string odat = oauth_catenc(3, http_request_method.c_str(), (*argvp)[0].c_str(), query.c_str()); // base-string
-#ifdef DEBUG_OAUTH
- fprintf (stderr, "\nliboauth: data to sign='%s'\n\n", odat.c_str());
- fprintf (stderr, "\nliboauth: key='%s'\n\n", okey.c_str());
-#endif
- switch(method) {
- //case OA_RSA:
- // sign = oauth_sign_rsa_sha1(odat.c_str(), okey.c_str()); // XXX okey needs to be RSA key!
- // break;
- case OA_PLAINTEXT:
- sign = oauth_sign_plaintext(odat.c_str(), okey.c_str()).c_str();
- break;
- default:
- sign = oauth_sign_hmac_sha1(odat.c_str(), okey.c_str());
- break;
- }
-
- // append signature to query args.
- snprintf(oarg, 1024, "oauth_signature=%s",sign.c_str());
- argvp->push_back(oarg);
-}
-
-std::string oauth_sign_array2(
- std::vector<std::string> *argvp,
- std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
-)
-{
-
- std::string result;
- oauth_sign_array2_process(argvp, postargs, method, http_method, c_key, c_secret, t_key, t_secret);
-
- // build URL params
- result = oauth_serialize_url(*argvp, (postargs?1:0));
-
- if (postargs) {
- *postargs = result;
- result = argvp->at(0);
- }
-
- return result;
-}
-
--- a/oauth.h Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,476 +0,0 @@
-/**
- * @brief OAuth.net implementation in POSIX-C.
- * @file oauth.h
- * @author Robin Gareus <robin@gareus.org>
- *
- * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-#ifndef _OAUTH_H
-#define _OAUTH_H 1
-
-#include <vector>
-#include <string>
-
-#include <stdlib.h>
-
-#ifndef DOXYGEN_IGNORE
-// liboauth version
-#define LIBOAUTH_VERSION "0.8.9"
-#define LIBOAUTH_VERSION_MAJOR 0
-#define LIBOAUTH_VERSION_MINOR 8
-#define LIBOAUTH_VERSION_MICRO 9
-
-//interface revision number
-//http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-#define LIBOAUTH_CUR 7
-#define LIBOAUTH_REV 0
-#define LIBOAUTH_AGE 7
-#endif
-
-#ifdef __GNUC__
-# define OA_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
-#else
-# define OA_GCC_VERSION_AT_LEAST(x,y) 0
-#endif
-
-#ifndef attribute_deprecated
-#if OA_GCC_VERSION_AT_LEAST(3,1)
-# define attribute_deprecated __attribute__((deprecated))
-#else
-# define attribute_deprecated
-#endif
-#endif
-
-/** \enum OAuthMethod
- * signature method to used for signing the request.
- */
-typedef enum {
- OA_HMAC=0, ///< use HMAC-SHA1 request signing method
- OA_RSA, ///< use RSA signature
- OA_PLAINTEXT ///< use plain text signature (for testing only)
- } OAuthMethod;
-
-/**
- * Base64 encode and return size data in 'src'. The caller must free the
- * returned string.
- *
- * @param size The size of the data in src
- * @param src The data to be base64 encode
- * @return encoded string otherwise NULL
- */
-std::string oauth_encode_base64(const unsigned char *src, int size);
-
-/**
- * Decode the base64 encoded string 'src' into the memory pointed to by
- * 'dest'.
- *
- * @param dest Pointer to memory for holding the decoded string.
- * Must be large enough to receive the decoded string.
- * @param src A base64 encoded string.
- * @return the length of the decoded string if decode
- * succeeded otherwise 0.
- */
-std::string oauth_decode_base64(const char *src);
-
-/**
- * Escape 'string' according to RFC3986 and
- * http://oauth.net/core/1.0/#encoding_parameters.
- *
- * @param string The data to be encoded
- * @return encoded string otherwise NULL
- * The caller must free the returned string.
- */
-std::string oauth_url_escape(const char *string);
-
-/**
- * Parse RFC3986 encoded 'string' back to unescaped version.
- *
- * @param string The data to be unescaped
- * @param olen unless NULL the length of the returned string is stored there.
- * @return decoded string or NULL
- * The caller must free the returned string.
- */
-std::string oauth_url_unescape(const char *string);
-
-
-/**
- * returns base64 encoded HMAC-SHA1 signature for
- * given message and key.
- * both data and key need to be urlencoded.
- *
- * the returned string needs to be freed by the caller
- *
- * @param m message to be signed
- * @param k key used for signing
- * @return signature string.
- */
-std::string oauth_sign_hmac_sha1 (const char *m, const char *k);
-
-/**
- * same as \ref oauth_sign_hmac_sha1 but allows
- * to specify length of message and key (in case they contain null chars).
- *
- * @param m message to be signed
- * @param ml length of message
- * @param k key used for signing
- * @param kl length of key
- * @return signature string.
- */
-std::string oauth_sign_hmac_sha1_raw(const char *m, const size_t ml, const char *k, const size_t kl);
-
-/**
- * returns plaintext signature for the given key.
- *
- * the returned string needs to be freed by the caller
- *
- * @param m message to be signed
- * @param k key used for signing
- * @return signature string
- */
-std::string oauth_sign_plaintext(const char *m, const char *k);
-
-/**
- * returns RSA-SHA1 signature for given data.
- * the returned signature needs to be freed by the caller.
- *
- * @param m message to be signed
- * @param k private-key PKCS and Base64-encoded
- * @return base64 encoded signature string.
- */
-//std::string oauth_sign_rsa_sha1 (const char *m, const char *k);
-
-/**
- * verify RSA-SHA1 signature.
- *
- * returns the output of EVP_VerifyFinal() for a given message,
- * cert/pubkey and signature.
- *
- * @param m message to be verified
- * @param c public-key or x509 certificate
- * @param s base64 encoded signature
- * @return 1 for a correct signature, 0 for failure and -1 if some other error occurred
- */
-int oauth_verify_rsa_sha1(const char *m, const char *c, const char *s);
-
-/**
- * url-escape strings and concatenate with '&' separator.
- * The number of strings to be concatenated must be
- * given as first argument.
- * all arguments thereafter must be of type (char *)
- *
- * @param len the number of arguments to follow this parameter
- *
- * @return pointer to memory holding the concatenated
- * strings - needs to be free(d) by the caller. or NULL
- * in case we ran out of memory.
- */
-std::string oauth_catenc(int len, ...);
-
-/**
- * splits the given url into a parameter array.
- * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
- * (see \ref oauth_split_post_paramters for a more generic version)
- *
- * @param url the url or query-string to parse; may be NULL
- * @param argv pointer to a (char *) array where the results are stored.
- * The array is re-allocated to match the number of parameters and each
- * parameter-string is allocated with strdup. - The memory needs to be freed
- * by the caller.
- *
- * @return number of parameter(s) in array.
- */
-void oauth_split_url_parameters(const char *url, char ***argv);
-
-/**
- * splits the given url into a parameter array.
- * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
- *
- * @param url the url or query-string to parse.
- * @param argv pointer to a (char *) array where the results are stored.
- * The array is re-allocated to match the number of parameters and each
- * parameter-string is allocated with strdup. - The memory needs to be freed
- * by the caller.
- * @param qesc use query parameter escape (vs post-param-escape) - if set
- * to 1 all '+' are treated as spaces ' '
- *
- * @return number of parameter(s) in array.
- */
-void oauth_split_post_paramters(const char *url, char ***argv, short qesc);
-
-/**
- * build a url query string from an array.
- *
- * @param argc the total number of elements in the array
- * @param start element in the array at which to start concatenating.
- * @param argv parameter-array to concatenate.
- * @return url string needs to be freed by the caller.
- *
- */
-std::string oauth_serialize_url (std::vector<std::string> const &argv, int start);
-
-/**
- * encode query parameters from an array.
- *
- * @param argc the total number of elements in the array
- * @param start element in the array at which to start concatenating.
- * @param argv parameter-array to concatenate.
- * @param sep separator for parameters (usually "&")
- * @param mod - bitwise modifiers:
- * 1: skip all values that start with "oauth_"
- * 2: skip all values that don't start with "oauth_"
- * 4: double quotation marks are added around values (use with sep ", " for HTTP Authorization header).
- * @return url string needs to be freed by the caller.
- */
-std::string oauth_serialize_url_sep (std::vector<std::string> const &argv, int start, char const *sep, int mod);
-
-/**
- * build a query parameter string from an array.
- *
- * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv).
- * It strips the leading host/path, which is usually the first
- * element when using oauth_split_url_parameters on an URL.
- *
- * @param argc the total number of elements in the array
- * @param argv parameter-array to concatenate.
- * @return url string needs to be freed by the caller.
- */
-std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv);
-
-/**
- * generate a random string between 15 and 32 chars length
- * and return a pointer to it. The value needs to be freed by the
- * caller
- *
- * @return zero terminated random string.
- */
-std::string oauth_gen_nonce();
-
-/**
- * string compare function for oauth parameters.
- *
- * used with qsort. needed to normalize request parameters.
- * see http://oauth.net/core/1.0/#anchor14
- */
-int oauth_cmpstringp(const void *p1, const void *p2);
-
-
-/**
- * search array for parameter key.
- * @param argv length of array to search
- * @param argc parameter array to search
- * @param key key of parameter to check.
- *
- * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise.
- */
-bool oauth_param_exists(std::vector<std::string> const &argv, char const *key);
-
-/**
- * free array args
- *
- * @param argcp pointer to array length int
- * @param argvp pointer to array values to be free()d
- */
-void oauth_free_array(int *argcp, std::vector<std::string> *argvp);
-
-/**
- * calculate OAuth-signature for a given HTTP request URL, parameters and oauth-tokens.
- *
- * if 'postargs' is NULL a "GET" request is signed and the
- * signed URL is returned. Else this fn will modify 'postargs'
- * to point to memory that contains the signed POST-variables
- * and returns the base URL.
- *
- * both, the return value and (if given) 'postargs' need to be freed
- * by the caller.
- *
- * @param url The request URL to be signed. append all GET or POST
- * query-parameters separated by either '?' or '&' to this parameter.
- *
- * @param postargs This parameter points to an area where the return value
- * is stored. If 'postargs' is NULL, no value is stored.
- *
- * @param method specify the signature method to use. It is of type
- * \ref OAuthMethod and most likely \ref OA_HMAC.
- *
- * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
- * If NULL is given as 'http_method' this defaults to "GET" when
- * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
- *
- * @param c_key consumer key
- * @param c_secret consumer secret
- * @param t_key token key
- * @param t_secret token secret
- *
- * @return the signed url or NULL if an error occurred.
- *
- */
-std::string oauth_sign_url2 (const char *url, std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
- );
-
-/**
- * @deprecated Use oauth_sign_url2() instead.
- */
-std::string oauth_sign_url (const char *url, std::string *postargs,
- OAuthMethod method,
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
- ) attribute_deprecated;
-
-
-/**
- * the back-end behind by /ref oauth_sign_array2.
- * however it does not serialize the signed URL again.
- * The user needs to call /ref oauth_serialize_url (oA)
- * and /ref oauth_free_array to do so.
- *
- * This allows to split parts of the URL to be used for
- * OAuth HTTP Authorization header:
- * see http://oauth.net/core/1.0a/#consumer_req_param
- * the oauthtest2 example code does so.
- *
- *
- * @param argcp pointer to array length int
- * @param argvp pointer to array values
- * (argv[0]="http://example.org:80/" argv[1]="first=QueryParamater" ..
- * the array is modified: fi. oauth_ parameters are added)
- * These arrays can be generated with /ref oauth_split_url_parameters
- * or /ref oauth_split_post_paramters.
- *
- * @param postargs This parameter points to an area where the return value
- * is stored. If 'postargs' is NULL, no value is stored.
- *
- * @param method specify the signature method to use. It is of type
- * \ref OAuthMethod and most likely \ref OA_HMAC.
- *
- * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
- * If NULL is given as 'http_method' this defaults to "GET" when
- * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
- *
- * @param c_key consumer key
- * @param c_secret consumer secret
- * @param t_key token key
- * @param t_secret token secret
- *
- * @return void
- *
- */
-void oauth_sign_array2_process (std::vector<std::string> *argvp,
- std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
- );
-
-/**
- * same as /ref oauth_sign_url
- * with the url already split into parameter array
- *
- * @param argcp pointer to array length int
- * @param argvp pointer to array values
- * (argv[0]="http://example.org:80/" argv[1]="first=QueryParamater" ..
- * the array is modified: fi. oauth_ parameters are added)
- * These arrays can be generated with /ref oauth_split_url_parameters
- * or /ref oauth_split_post_paramters.
- *
- * @param postargs This parameter points to an area where the return value
- * is stored. If 'postargs' is NULL, no value is stored.
- *
- * @param method specify the signature method to use. It is of type
- * \ref OAuthMethod and most likely \ref OA_HMAC.
- *
- * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
- * If NULL is given as 'http_method' this defaults to "GET" when
- * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
- *
- * @param c_key consumer key
- * @param c_secret consumer secret
- * @param t_key token key
- * @param t_secret token secret
- *
- * @return the signed url or NULL if an error occurred.
- */
-std::string oauth_sign_array2 (std::vector<std::string> *argvp,
- std::string *postargs,
- OAuthMethod method,
- const char *http_method, //< HTTP request method
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
- );
-
-/**
- * @deprecated Use oauth_sign_array2() instead.
- */
-char *oauth_sign_array(
- std::vector<std::string> *argvp,
- char **postargs,
- OAuthMethod method,
- const char *c_key, //< consumer key - posted plain text
- const char *c_secret, //< consumer secret - used as 1st part of secret-key
- const char *t_key, //< token key - posted plain text in URL
- const char *t_secret //< token secret - used as 2st part of secret-key
- ) attribute_deprecated;
-
-/**
- * do a HTTP POST request, wait for it to finish
- * and return the content of the reply.
- * (requires libcurl or a command-line HTTP client)
- *
- * If compiled <b>without</b> libcurl this function calls
- * a command-line executable defined in the environment variable
- * OAUTH_HTTP_CMD - it defaults to
- * <tt>curl -sA 'liboauth-agent/0.1' -d '%%p' '%%u'</tt>
- * where %%p is replaced with the postargs and %%u is replaced with
- * the URL.
- *
- * bash & wget example:
- * <tt>export OAUTH_HTTP_CMD="wget -q -U 'liboauth-agent/0.1' --post-data='%p' '%u' "</tt>
- *
- * NOTE: This function uses the curl's default HTTP-POST Content-Type:
- * application/x-www-form-urlencoded which is the only option allowed
- * by oauth core 1.0 spec. Experimental code can use the Environment variable
- * to transmit custom HTTP headers or parameters.
- *
- * WARNING: this is a tentative function. it's convenient and handy for testing
- * or developing OAuth code. But don't rely on this function
- * to become a stable part of this API. It does not do
- * much error checking for one thing..
- *
- * @param u url to query
- * @param p postargs to send along with the HTTP request.
- * @return replied content from HTTP server. needs to be freed by caller.
- */
-std::string oauth_http_post(const char *u, const char *p);
-
-#endif
--- a/oauth_http.cpp Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * OAuth http functions in POSIX-C.
- *
- * Copyright 2007, 2008, 2009, 2010 Robin Gareus <robin@gareus.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "oauth.h"
-
-#include <HTTPClient.h>
-#include "HTTPPostText.h"
-
-static char res_buffer[1024] = "";
-
-/* wrapper functions */
-
-/**
- * do a HTTP POST request, wait for it to finish
- * and return the content of the reply.
- * (requires libcurl or a command-line HTTP client)
- *
- * more documentation in oauth.h
- *
- * @param u url to query
- * @param p postargs to send along with the HTTP request.
- * @return In case of an error NULL is returned; otherwise a pointer to the
- * replied content from HTTP server. latter needs to be freed by caller.
- */
-std::string oauth_http_post(const char *u, const char *p)
-{
- HTTPClient http;
- HTTPPostText req((char *)p, strlen(p) + 1);
- HTTPText res(res_buffer, sizeof(res_buffer));
- http.post(u, req, &res);
- return res_buffer;
-}
-
--- a/sha1.c Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-/*
- * sha1.c
- *
- * Description:
- * This file implements the Secure Hashing Algorithm 1 as
- * defined in FIPS PUB 180-1 published April 17, 1995.
- *
- * The SHA-1, produces a 160-bit message digest for a given
- * data stream. It should take about 2**n steps to find a
- * message with the same digest as a given message and
- * 2**(n/2) to find any two messages with the same digest,
- * when n is the digest size in bits. Therefore, this
- * algorithm can serve as a means of providing a
- * "fingerprint" for a message.
- *
- * Portability Issues:
- * SHA-1 is defined in terms of 32-bit "words". This code
- * uses <stdint.h> (included via "sha1.h" to define 32 and 8
- * bit unsigned integer types. If your C compiler does not
- * support 32 bit unsigned integers, this code is not
- * appropriate.
- *
- * Caveats:
- * SHA-1 is designed to work with messages less than 2^64 bits
- * long. Although SHA-1 allows a message digest to be generated
- * for messages of any number of bits less than 2^64, this
- * implementation only works with messages with a length that is
- * a multiple of the size of an 8-bit character.
- *
- */
-
-#include "sha1.h"
-
-
-/*
- * Define the SHA1 circular left shift macro
- */
-#define SHA1CircularShift(bits,word) \
- (((word) << (bits)) | ((word) >> (32-(bits))))
-
-/* Local Function Prototyptes */
-void SHA1PadMessage(SHA1Context *);
-void SHA1ProcessMessageBlock(SHA1Context *);
-
-/*
- * SHA1Reset
- *
- * Description:
- * This function will initialize the SHA1Context in preparation
- * for computing a new SHA1 message digest.
- *
- * Parameters:
- * context: [in/out]
- * The context to reset.
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Reset(SHA1Context *context)
-{
- if (!context)
- {
- return shaNull;
- }
-
- context->Length_Low = 0;
- context->Length_High = 0;
- context->Message_Block_Index = 0;
-
- context->Intermediate_Hash[0] = 0x67452301;
- context->Intermediate_Hash[1] = 0xEFCDAB89;
- context->Intermediate_Hash[2] = 0x98BADCFE;
- context->Intermediate_Hash[3] = 0x10325476;
- context->Intermediate_Hash[4] = 0xC3D2E1F0;
-
- context->Computed = 0;
- context->Corrupted = 0;
-
- return shaSuccess;
-}
-
-/*
- * SHA1Result
- *
- * Description:
- * This function will return the 160-bit message digest into the
- * Message_Digest array provided by the caller.
- * NOTE: The first octet of hash is stored in the 0th element,
- * the last octet of hash in the 19th element.
- *
- * Parameters:
- * context: [in/out]
- * The context to use to calculate the SHA-1 hash.
- * Message_Digest: [out]
- * Where the digest is returned.
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Result( SHA1Context *context,
- uint8_t Message_Digest[SHA1HashSize])
-{
- int i;
-
- if (!context || !Message_Digest)
- {
- return shaNull;
- }
-
- if (context->Corrupted)
- {
- return context->Corrupted;
- }
-
- if (!context->Computed)
- {
- SHA1PadMessage(context);
- for(i=0; i<64; ++i)
- {
- /* message may be sensitive, clear it out */
- context->Message_Block[i] = 0;
- }
- context->Length_Low = 0; /* and clear length */
- context->Length_High = 0;
- context->Computed = 1;
- }
-
- for(i = 0; i < SHA1HashSize; ++i)
- {
- Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
- }
-
- return shaSuccess;
-}
-
-/*
- * SHA1Input
- *
- * Description:
- * This function accepts an array of octets as the next portion
- * of the message.
- *
- * Parameters:
- * context: [in/out]
- * The SHA context to update
- * message_array: [in]
- * An array of characters representing the next portion of
- * the message.
- * length: [in]
- * The length of the message in message_array
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Input( SHA1Context *context,
- const uint8_t *message_array,
- unsigned length)
-{
- if (!length)
- {
- return shaSuccess;
- }
-
- if (!context || !message_array)
- {
- return shaNull;
- }
-
- if (context->Computed)
- {
- context->Corrupted = shaStateError;
- return shaStateError;
- }
-
- if (context->Corrupted)
- {
- return context->Corrupted;
- }
- while(length-- && !context->Corrupted)
- {
- context->Message_Block[context->Message_Block_Index++] =
- (*message_array & 0xFF);
-
- context->Length_Low += 8;
- if (context->Length_Low == 0)
- {
- context->Length_High++;
- if (context->Length_High == 0)
- {
- /* Message is too long */
- context->Corrupted = 1;
- }
- }
-
- if (context->Message_Block_Index == 64)
- {
- SHA1ProcessMessageBlock(context);
- }
-
- message_array++;
- }
-
- return shaSuccess;
-}
-
-/*
- * SHA1ProcessMessageBlock
- *
- * Description:
- * This function will process the next 512 bits of the message
- * stored in the Message_Block array.
- *
- * Parameters:
- * None.
- *
- * Returns:
- * Nothing.
- *
- * Comments:
- * Many of the variable names in this code, especially the
- * single character names, were used because those were the
- * names used in the publication.
- *
- *
- */
-void SHA1ProcessMessageBlock(SHA1Context *context)
-{
- const uint32_t K[] = { /* Constants defined in SHA-1 */
- 0x5A827999,
- 0x6ED9EBA1,
- 0x8F1BBCDC,
- 0xCA62C1D6
- };
- int t; /* Loop counter */
- uint32_t temp; /* Temporary word value */
- uint32_t W[80]; /* Word sequence */
- uint32_t A, B, C, D, E; /* Word buffers */
-
- /*
- * Initialize the first 16 words in the array W
- */
- for(t = 0; t < 16; t++)
- {
- W[t] = context->Message_Block[t * 4] << 24;
- W[t] |= context->Message_Block[t * 4 + 1] << 16;
- W[t] |= context->Message_Block[t * 4 + 2] << 8;
- W[t] |= context->Message_Block[t * 4 + 3];
- }
-
- for(t = 16; t < 80; t++)
- {
- W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
- }
-
- A = context->Intermediate_Hash[0];
- B = context->Intermediate_Hash[1];
- C = context->Intermediate_Hash[2];
- D = context->Intermediate_Hash[3];
- E = context->Intermediate_Hash[4];
-
- for(t = 0; t < 20; t++)
- {
- temp = SHA1CircularShift(5,A) +
- ((B & C) | ((~B) & D)) + E + W[t] + K[0];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for(t = 20; t < 40; t++)
- {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for(t = 40; t < 60; t++)
- {
- temp = SHA1CircularShift(5,A) +
- ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for(t = 60; t < 80; t++)
- {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- context->Intermediate_Hash[0] += A;
- context->Intermediate_Hash[1] += B;
- context->Intermediate_Hash[2] += C;
- context->Intermediate_Hash[3] += D;
- context->Intermediate_Hash[4] += E;
-
- context->Message_Block_Index = 0;
-}
-
-
-/*
- * SHA1PadMessage
- *
- * Description:
- * According to the standard, the message must be padded to an even
- * 512 bits. The first padding bit must be a '1'. The last 64
- * bits represent the length of the original message. All bits in
- * between should be 0. This function will pad the message
- * according to those rules by filling the Message_Block array
- * accordingly. It will also call the ProcessMessageBlock function
- * provided appropriately. When it returns, it can be assumed that
- * the message digest has been computed.
- *
- * Parameters:
- * context: [in/out]
- * The context to pad
- * ProcessMessageBlock: [in]
- * The appropriate SHA*ProcessMessageBlock function
- * Returns:
- * Nothing.
- *
- */
-
-void SHA1PadMessage(SHA1Context *context)
-{
- /*
- * Check to see if the current message block is too small to hold
- * the initial padding bits and length. If so, we will pad the
- * block, process it, and then continue padding into a second
- * block.
- */
- if (context->Message_Block_Index > 55)
- {
- context->Message_Block[context->Message_Block_Index++] = 0x80;
- while(context->Message_Block_Index < 64)
- {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
-
- SHA1ProcessMessageBlock(context);
-
- while(context->Message_Block_Index < 56)
- {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
- }
- else
- {
- context->Message_Block[context->Message_Block_Index++] = 0x80;
- while(context->Message_Block_Index < 56)
- {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
- }
-
- /*
- * Store the message length as the last 8 octets
- */
- context->Message_Block[56] = context->Length_High >> 24;
- context->Message_Block[57] = context->Length_High >> 16;
- context->Message_Block[58] = context->Length_High >> 8;
- context->Message_Block[59] = context->Length_High;
- context->Message_Block[60] = context->Length_Low >> 24;
- context->Message_Block[61] = context->Length_Low >> 16;
- context->Message_Block[62] = context->Length_Low >> 8;
- context->Message_Block[63] = context->Length_Low;
-
- SHA1ProcessMessageBlock(context);
-}
-
--- a/sha1.h Mon Dec 15 12:24:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * sha1.h
- *
- * Description:
- * This is the header file for code which implements the Secure
- * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
- * April 17, 1995.
- *
- * Many of the variable names in this code, especially the
- * single character names, were used because those were the names
- * used in the publication.
- *
- * Please read the file sha1.c for more information.
- *
- */
-
-#ifndef _SHA1_H_
-#define _SHA1_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//#include <stdint.h>
-typedef unsigned long uint32_t;
-typedef int int_least16_t;
-typedef unsigned char uint8_t;
-
-/*
- * If you do not have the ISO standard stdint.h header file, then you
- * must typdef the following:
- * name meaning
- * uint32_t unsigned 32 bit integer
- * uint8_t unsigned 8 bit integer (i.e., unsigned char)
- * int_least16_t integer of >= 16 bits
- *
- */
-
-#ifndef _SHA_enum_
-#define _SHA_enum_
-enum
-{
- shaSuccess = 0,
- shaNull, /* Null pointer parameter */
- shaInputTooLong, /* input data too long */
- shaStateError /* called Input after Result */
-};
-#endif
-#define SHA1HashSize 20
-
-/*
- * This structure will hold context information for the SHA-1
- * hashing operation
- */
-typedef struct SHA1Context
-{
- uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */
-
- uint32_t Length_Low; /* Message length in bits */
- uint32_t Length_High; /* Message length in bits */
-
- /* Index into message block array */
- int_least16_t Message_Block_Index;
- uint8_t Message_Block[64]; /* 512-bit message blocks */
-
- int Computed; /* Is the digest computed? */
- int Corrupted; /* Is the message digest corrupted? */
-} SHA1Context;
-
-/*
- * Function Prototypes
- */
-
-int SHA1Reset( SHA1Context *);
-int SHA1Input( SHA1Context *,
- const uint8_t *,
- unsigned int);
-int SHA1Result( SHA1Context *,
- uint8_t Message_Digest[SHA1HashSize]);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/twicpps/hash.cpp Wed Jul 08 03:52:54 2015 +0000
@@ -0,0 +1,56 @@
+
+#include <string.h>
+
+#include "oauth.h" // base64 encode fn's.
+#include "sha1.h"
+
+void hmac_sha1(unsigned char const *key, size_t keylen, unsigned char const *in, size_t inlen, unsigned char *resbuf)
+{
+ struct SHA1Context inner;
+ struct SHA1Context outer;
+ unsigned char tmpkey[20];
+ unsigned char digest[20];
+ unsigned char block[64];
+
+ const int IPAD = 0x36;
+ const int OPAD = 0x5c;
+
+ if (keylen > 64) {
+ struct SHA1Context keyhash;
+ SHA1Reset(&keyhash);
+ SHA1Input(&keyhash, key, keylen);
+ SHA1Result(&keyhash, tmpkey);
+ key = tmpkey;
+ keylen = 20;
+ }
+
+ for (size_t i = 0; i < sizeof(block); i++) {
+ block[i] = IPAD ^ (i < keylen ? key[i] : 0);
+ }
+ SHA1Reset(&inner);
+ SHA1Input(&inner, block, 64);
+ SHA1Input(&inner, in, inlen);
+ SHA1Result(&inner, digest);
+
+ for (size_t i = 0; i < sizeof(block); i++) {
+ block[i] = OPAD ^ (i < keylen ? key[i] : 0);
+ }
+ SHA1Reset(&outer);
+ SHA1Input(&outer, block, 64);
+ SHA1Input(&outer, digest, 20);
+ SHA1Result(&outer, resbuf);
+}
+
+
+std::string oauth_sign_hmac_sha1(const char *m, const char *k)
+{
+ return oauth_sign_hmac_sha1_raw(m, strlen(m), k, strlen(k));
+}
+
+std::string oauth_sign_hmac_sha1_raw(const char *m, const size_t ml, const char *k, const size_t kl)
+{
+ unsigned char result[20];
+ hmac_sha1((unsigned char const *)k, kl, (unsigned char const *)m, ml, result);
+ return oauth_encode_base64(result, 20);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/twicpps/oauth.cpp Wed Jul 08 03:52:54 2015 +0000
@@ -0,0 +1,727 @@
+/*
+ * OAuth string functions in POSIX-C.
+ *
+ * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
+ *
+ * The base64 functions are by Jan-Henrik Haukeland, <hauk@tildeslash.com>
+ * and un/escape_url() was inspired by libcurl's curl_escape under ISC-license
+ * many thanks to Daniel Stenberg <daniel@haxx.se>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define WIPE_MEMORY ///< overwrite sensitve data before free()ing it.
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include <ctype.h> // isxdigit
+
+#include "oauth.h"
+
+#ifndef WIN32 // getpid() on POSIX systems
+//#include <sys/types.h>
+//#include <unistd.h>
+#else
+#define snprintf _snprintf
+#define strncasecmp strnicmp
+#pragma warning(disable:4996)
+#endif
+
+#include <vector>
+#include <algorithm>
+#include <sstream>
+
+/**
+ * Base64 encode one byte
+ */
+char oauth_b64_encode(unsigned char u)
+{
+ if (u < 26) return 'A' + u;
+ if (u < 52) return 'a' + (u - 26);
+ if (u < 62) return '0' + (u - 52);
+ if (u == 62) return '+';
+ return '/';
+}
+
+/**
+ * Decode a single base64 character.
+ */
+unsigned char oauth_b64_decode(char c)
+{
+ if (c >= 'A' && c <= 'Z') return(c - 'A');
+ if (c >= 'a' && c <= 'z') return(c - 'a' + 26);
+ if (c >= '0' && c <= '9') return(c - '0' + 52);
+ if (c == '+') return 62;
+ return 63;
+}
+
+/**
+ * Return TRUE if 'c' is a valid base64 character, otherwise FALSE
+ */
+bool oauth_b64_is_base64(char c)
+{
+ return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/') || (c == '='));
+}
+
+/**
+ * Base64 encode and return size data in 'src'. The caller must free the
+ * returned string.
+ *
+ * @param size The size of the data in src
+ * @param src The data to be base64 encode
+ * @return encoded string otherwise NULL
+ */
+std::string oauth_encode_base64(const unsigned char *src, int size)
+{
+ int i;
+ std::stringbuf sb;
+
+ if (!src) return NULL;
+ if (!size) size= strlen((char *)src);
+
+ for (i = 0; i < size; i += 3) {
+ unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0;
+ b1= src[i];
+ if (i + 1 < size) b2 = src[i + 1];
+ if (i + 2 < size) b3 = src[i + 2];
+
+ b4= b1 >> 2;
+ b5= ((b1 & 0x3) << 4) | (b2 >> 4);
+ b6= ((b2 & 0xf) << 2) | (b3 >> 6);
+ b7= b3 & 0x3f;
+
+ sb.sputc(oauth_b64_encode(b4));
+ sb.sputc(oauth_b64_encode(b5));
+
+ if (i + 1 < size) {
+ sb.sputc(oauth_b64_encode(b6));
+ } else {
+ sb.sputc('=');
+ }
+
+ if (i + 2 < size) {
+ sb.sputc(oauth_b64_encode(b7));
+ } else {
+ sb.sputc('=');
+ }
+ }
+ return sb.str();
+}
+
+/**
+ * Decode the base64 encoded string 'src' into the memory pointed to by
+ * 'dest'.
+ *
+ * @param dest Pointer to memory for holding the decoded string.
+ * Must be large enough to receive the decoded string.
+ * @param src A base64 encoded string.
+ * @return the length of the decoded string if decode
+ * succeeded otherwise 0.
+ */
+std::string oauth_decode_base64(const char *src)
+{
+ if (src && *src) {
+ std::stringbuf sb;
+ //unsigned char *p= dest;
+ int k, l= strlen(src)+1;
+ std::vector<unsigned char> buf(l);
+
+ /* Ignore non base64 chars as per the POSIX standard */
+ for (k = 0, l = 0; src[k]; k++) {
+ if (oauth_b64_is_base64(src[k])) {
+ buf[l++]= src[k];
+ }
+ }
+
+ for (k = 0; k < l; k += 4) {
+ char c1='A', c2='A', c3='A', c4='A';
+ unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+ c1= buf[k];
+
+ if (k + 1 < l) c2 = buf[k + 1];
+ if (k + 2 < l) c3 = buf[k + 2];
+ if (k + 3 < l) c4 = buf[k + 3];
+
+ b1 = oauth_b64_decode(c1);
+ b2 = oauth_b64_decode(c2);
+ b3 = oauth_b64_decode(c3);
+ b4 = oauth_b64_decode(c4);
+
+ sb.sputc((b1 << 2) | (b2 >> 4));
+
+ if (c3 != '=') sb.sputc(((b2 & 0xf) << 4) | (b3 >> 2));
+ if (c4 != '=') sb.sputc(((b3 & 0x3) << 6) | b4);
+ }
+
+ return sb.str();
+ }
+ return 0;
+}
+
+/**
+ * Escape 'string' according to RFC3986 and
+ * http://oauth.net/core/1.0/#encoding_parameters.
+ *
+ * @param string The data to be encoded
+ * @return encoded string otherwise NULL
+ * The caller must free the returned string.
+ */
+std::string oauth_url_escape(const char *string)
+{
+ unsigned char in;
+ size_t length;
+
+ if (!string) {
+ return std::string();
+ }
+
+ length = strlen(string);
+
+ std::stringbuf sb;
+
+ while (length--) {
+ in = *string;
+ if (strchr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_~.-", in)) {
+ sb.sputc(in);
+ } else {
+ char tmp[10];
+ snprintf(tmp, 4, "%%%02X", in);
+ sb.sputc(tmp[0]);
+ sb.sputc(tmp[1]);
+ sb.sputc(tmp[2]);
+ }
+ string++;
+ }
+ return sb.str();
+}
+
+#ifndef ISXDIGIT
+# define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#endif
+
+/**
+ * Parse RFC3986 encoded 'string' back to unescaped version.
+ *
+ * @param string The data to be unescaped
+ * @param olen unless NULL the length of the returned string is stored there.
+ * @return decoded string or NULL
+ * The caller must free the returned string.
+ */
+std::string oauth_url_unescape(const char *string)
+{
+ size_t alloc, strindex=0;
+ unsigned char in;
+ long hex;
+
+ if (!string) return NULL;
+
+ alloc = strlen(string)+1;
+ std::vector<char> ns(alloc);
+
+ while(--alloc > 0) {
+ in = *string;
+ if (('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
+ char hexstr[3]; // '%XX'
+ hexstr[0] = string[1];
+ hexstr[1] = string[2];
+ hexstr[2] = 0;
+ hex = strtol(hexstr, NULL, 16);
+ in = (unsigned char)hex; /* hex is always < 256 */
+ string += 2;
+ alloc -= 2;
+ }
+ ns[strindex++] = in;
+ string++;
+ }
+ ns[strindex]=0;
+ return &ns[0];
+}
+
+/**
+ * returns plaintext signature for the given key.
+ *
+ * the returned string needs to be freed by the caller
+ *
+ * @param m message to be signed
+ * @param k key used for signing
+ * @return signature string
+ */
+std::string oauth_sign_plaintext (const char *m, const char *k)
+{
+ return oauth_url_escape(k);
+}
+
+/**
+ * encode strings and concatenate with '&' separator.
+ * The number of strings to be concatenated must be
+ * given as first argument.
+ * all arguments thereafter must be of type (char *)
+ *
+ * @param len the number of arguments to follow this parameter
+ * @param ... string to escape and added (may be NULL)
+ *
+ * @return pointer to memory holding the concatenated
+ * strings - needs to be free(d) by the caller. or NULL
+ * in case we ran out of memory.
+ */
+std::string oauth_catenc(int len, ...)
+{
+ va_list va;
+ std::string str;
+ va_start(va, len);
+ for (int i = 0; i < len; i++) {
+ char *arg = va_arg(va, char *);
+ std::string enc = oauth_url_escape(arg);
+ if (i > 0) str += "&";
+ str += enc;
+ }
+ va_end(va);
+ return str;
+}
+
+/**
+ * splits the given url into a parameter array.
+ * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
+ *
+ * NOTE: Request-parameters-values may include an ampersand character.
+ * However if unescaped this function will use them as parameter delimiter.
+ * If you need to make such a request, this function since version 0.3.5 allows
+ * to use the ASCII SOH (0x01) character as alias for '&' (0x26).
+ * (the motivation is convenience: SOH is /untypeable/ and much more
+ * unlikely to appear than '&' - If you plan to sign fancy URLs you
+ * should not split a query-string, but rather provide the parameter array
+ * directly to \ref oauth_serialize_url)
+ *
+ * @param url the url or query-string to parse.
+ * @param argv pointer to a (char *) array where the results are stored.
+ * The array is re-allocated to match the number of parameters and each
+ * parameter-string is allocated with strdup. - The memory needs to be freed
+ * by the caller.
+ * @param qesc use query parameter escape (vs post-param-escape) - if set
+ * to 1 all '+' are treated as spaces ' '
+ *
+ * @return number of parameter(s) in array.
+ */
+void oauth_split_post_paramters(const char *url, std::vector<std::string> *argv, short qesc)
+{
+ int argc=0;
+ char *token, *tmp;
+ if (!argv) return;
+ if (!url) return;
+ std::vector<char> t1(strlen(url) + 1);
+ strcpy(&t1[0], url);
+
+ // '+' represents a space, in a URL query string
+ while ((qesc&1) && (tmp=strchr(&t1[0],'+'))) *tmp = ' ';
+
+ tmp = &t1[0];
+ while ((token = strtok(tmp,"&?"))) {
+ if (!strncasecmp("oauth_signature=", token, 16)) continue;
+ while (!(qesc & 2) && (tmp = strchr(token, '\001'))) *tmp = '&';
+ argv->push_back(oauth_url_unescape(token));
+ if (argc == 0 && strstr(token, ":/")) {
+ // HTTP does not allow empty absolute paths, so the URL
+ // 'http://example.com' is equivalent to 'http://example.com/' and should
+ // be treated as such for the purposes of OAuth signing (rfc2616, section 3.2.1)
+ // see http://groups.google.com/group/oauth/browse_thread/thread/c44b6f061bfd98c?hl=en
+ char *slash = strstr(token, ":/");
+ while (slash && *(++slash) == '/') ; // skip slashes eg /xxx:[\/]*/
+#if 0
+ // skip possibly unescaped slashes in the userinfo - they're not allowed by RFC2396 but have been seen.
+ // the hostname/IP may only contain alphanumeric characters - so we're safe there.
+ if (slash && strchr(slash,'@')) slash=strchr(slash, '@');
+#endif
+ if (slash && !strchr(slash,'/')) {
+#ifdef DEBUG_OAUTH
+ fprintf(stderr, "\nliboauth: added trailing slash to URL: '%s'\n\n", token);
+#endif
+ argv->push_back(std::string(token) + "/");
+ }
+ }
+ if (argc == 0 && (tmp = strstr((char *)argv->at(argc).c_str(), ":80/"))) {
+ memmove(tmp, tmp + 3, strlen(tmp + 2));
+ }
+ tmp = NULL;
+ argc++;
+ }
+}
+
+void oauth_split_url_parameters(const char *url, std::vector<std::string> *argv)
+{
+ oauth_split_post_paramters(url, argv, 1);
+}
+
+/**
+ * build a url query string from an array.
+ *
+ * @param argc the total number of elements in the array
+ * @param start element in the array at which to start concatenating.
+ * @param argv parameter-array to concatenate.
+ * @return url string needs to be freed by the caller.
+ *
+ */
+std::string oauth_serialize_url (std::vector<std::string> const &argv, int start)
+{
+ return oauth_serialize_url_sep(argv, start, "&", 0);
+}
+
+/**
+ * encode query parameters from an array.
+ *
+ * @param argc the total number of elements in the array
+ * @param start element in the array at which to start concatenating.
+ * @param argv parameter-array to concatenate.
+ * @param sep separator for parameters (usually "&")
+ * @param mod - bitwise modifiers:
+ * 1: skip all values that start with "oauth_"
+ * 2: skip all values that don't start with "oauth_"
+ * 4: add double quotation marks around values (use with sep=", " to generate HTTP Authorization header).
+ * @return url string needs to be freed by the caller.
+ */
+std::string oauth_serialize_url_sep(std::vector<std::string> const &argv, int start, char const *sep, int mod)
+{
+ int i;
+ int first = 0;
+ int seplen = strlen(sep);
+ std::string query;
+ for (i = start; i < (int)argv.size(); i++) {
+ std::string tmp;
+
+ if ((mod & 1) == 1 && (strncmp(argv[i].c_str(), "oauth_", 6) == 0 || strncmp(argv[i].c_str(), "x_oauth_", 8) == 0)) continue;
+ if ((mod & 2) == 2 && (strncmp(argv[i].c_str(), "oauth_", 6) != 0 && strncmp(argv[i].c_str(), "x_oauth_", 8) != 0) && i != 0) continue;
+
+ if (i == start && i == 0 && strstr(argv[i].c_str(), ":/")) {
+ tmp = argv[i];
+ } else {
+ char *p = strchr((char *)argv[i].c_str(), '=');
+ if (p) {
+ tmp = oauth_url_escape(std::string(argv[i].c_str(), (char const *)p).c_str());
+ std::string t2 = oauth_url_escape(p + 1);
+ tmp += "=";
+ if (mod & 4) tmp += "\"";
+ tmp += t2;
+ if (mod & 4) tmp += "\"";
+ } else {
+ // see http://oauth.net/core/1.0/#anchor14
+ // escape parameter names and arguments but not the '='
+ tmp=argv[i];
+ tmp += "=";
+ }
+ }
+ query += ((i == start || first) ? "" : sep);
+ query += tmp;
+ first = 0;
+ if (i == start && i == 0 && strstr((char *)tmp.c_str(), ":/")) {
+ query += "?";
+ first = 1;
+ }
+ }
+ return (query);
+}
+
+/**
+ * build a query parameter string from an array.
+ *
+ * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv).
+ * It strips the leading host/path, which is usually the first
+ * element when using oauth_split_url_parameters on an URL.
+ *
+ * @param argc the total number of elements in the array
+ * @param argv parameter-array to concatenate.
+ * @return url string needs to be freed by the caller.
+ */
+std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv)
+{
+ return oauth_serialize_url(argv, 1);
+}
+
+/**
+ * generate a random string between 15 and 32 chars length
+ * and return a pointer to it. The value needs to be freed by the
+ * caller
+ *
+ * @return zero terminated random string.
+ */
+std::string oauth_gen_nonce()
+{
+ static const char *chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+ const unsigned int max = 26 + 26 + 10 + 1; //strlen(chars);
+ char tmp[50];
+ int i, len;
+
+ srand((unsigned int)time(0));
+ len = 15 + rand() % 16;
+ for (i = 0; i < len; i++) {
+ tmp[i] = chars[rand() % max];
+ }
+ tmp[i]='\0';
+ return &tmp[0];
+}
+
+/**
+ * string compare function for oauth parameters.
+ *
+ * used with qsort. needed to normalize request parameters.
+ * see http://oauth.net/core/1.0/#anchor14
+ */
+int oauth_cmpstringp(const void *p1, const void *p2)
+{
+ char const *e1;
+ char const *e2;
+ e1 = strchr((char *)p1, '=');
+ e2 = strchr((char *)p2, '=');
+ if (e1 && e2) {
+ std::string left((char const *)p1, e1);
+ std::string right((char const *)p2, e2);
+ return strcmp(left.c_str(), right.c_str());
+ }
+
+ std::string left = oauth_url_escape((char const *)p1);
+ std::string right = oauth_url_escape((char const *)p2);
+ return strcmp(left.c_str(), right.c_str());
+}
+
+bool oauth_cmpstringp_ex(std::string const &left, std::string const &right)
+{
+ return oauth_cmpstringp(left.c_str(), right.c_str()) < 0;
+}
+
+/**
+ * search array for parameter key.
+ * @param argv length of array to search
+ * @param argc parameter array to search
+ * @param key key of parameter to check.
+ *
+ * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise.
+ */
+bool oauth_param_exists(std::vector<std::string> const &argv, char const *key)
+{
+ int i;
+ size_t l = strlen(key);
+ for (i = 0; i < (int)argv.size(); i++) {
+ if (!strncmp(argv[i].c_str(), key, l) && argv[i][l] == '=') {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ *
+ */
+void oauth_add_protocol(
+ std::vector<std::string> *argvp,
+ OAuthMethod method,
+ const char *c_key, //< consumer key - posted plain text
+ const char *t_key //< token key - posted plain text in URL
+)
+{
+ char oarg[1024];
+
+ // add OAuth specific arguments
+ if (!oauth_param_exists(*argvp,"oauth_nonce")) {
+ std::string tmp = oauth_gen_nonce();
+ snprintf(oarg, 1024, "oauth_nonce=%s", tmp.c_str());
+ argvp->push_back(oarg);
+ }
+
+ if (!oauth_param_exists(*argvp,"oauth_timestamp")) {
+ snprintf(oarg, 1024, "oauth_timestamp=%li", (long int) time(NULL));
+ argvp->push_back(oarg);
+ }
+
+ if (t_key) {
+ snprintf(oarg, 1024, "oauth_token=%s", t_key);
+ argvp->push_back(oarg);
+ }
+
+ snprintf(oarg, 1024, "oauth_consumer_key=%s", c_key);
+ argvp->push_back(oarg);
+
+ snprintf(oarg, 1024, "oauth_signature_method=%s", method==0?"HMAC-SHA1":method==1?"RSA-SHA1":"PLAINTEXT");
+ argvp->push_back(oarg);
+
+ if (!oauth_param_exists(*argvp,"oauth_version")) {
+ snprintf(oarg, 1024, "oauth_version=1.0");
+ argvp->push_back(oarg);
+ }
+
+#if 0 // oauth_version 1.0 Rev A
+ if (!oauth_param_exists(argv,argc,"oauth_callback")) {
+ snprintf(oarg, 1024, "oauth_callback=oob");
+ argvp->push_back(oarg);
+ }
+#endif
+
+}
+
+std::string oauth_sign_url(
+ const char *url,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+)
+{
+ return oauth_sign_url2(url, postargs, method, NULL, c_key, c_sec, t_key, t_sec);
+}
+
+std::string oauth_sign_url2(
+ const char *url,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+)
+{
+ //char **argv = NULL;
+ std::vector<std::string> argv;
+ std::string rv;
+
+ if (postargs) {
+ oauth_split_post_paramters(url, &argv, 0);
+ } else {
+ oauth_split_url_parameters(url, &argv);
+ }
+
+ rv = oauth_sign_array2(&argv, postargs, method, http_method, c_key, c_sec, t_key, t_sec);
+
+ return(rv);
+}
+
+std::string oauth_sign_array(
+ std::vector<std::string> *argvp,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+)
+{
+ return oauth_sign_array2(
+ argvp,
+ postargs, method,
+ NULL,
+ c_key, c_sec,
+ t_key, t_sec
+ );
+}
+
+void oauth_sign_array2_process(
+ std::vector<std::string> *argvp,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+)
+{
+ char oarg[1024];
+ std::string query;
+ std::string sign;
+ std::string http_request_method;
+
+ if (!http_method) {
+ http_request_method = postargs ? "POST" : "GET";
+ } else {
+ std::vector<char> tmp(strlen(http_method) + 1);
+ int i;
+ for (i = 0; http_method[i]; i++) {
+ tmp[i] = toupper(http_method[i]);
+ }
+ tmp[i] = 0;
+ http_request_method = &tmp[0];
+ }
+
+ // add required OAuth protocol parameters
+ oauth_add_protocol(argvp, method, c_key, t_key);
+
+ // sort parameters
+ //qsort(&(*argvp)[1], (*argcp)-1, sizeof(char *), oauth_cmpstringp);
+ std::sort(argvp->begin() + 1, argvp->end(), oauth_cmpstringp_ex);
+
+ // serialize URL - base-url
+ query= oauth_serialize_url_parameters(*argvp);
+
+ // generate signature
+ std::string okey = oauth_catenc(2, c_sec, t_sec);
+ std::string odat = oauth_catenc(3, http_request_method.c_str(), (*argvp)[0].c_str(), query.c_str()); // base-string
+#ifdef DEBUG_OAUTH
+ fprintf (stderr, "\nliboauth: data to sign='%s'\n\n", odat.c_str());
+ fprintf (stderr, "\nliboauth: key='%s'\n\n", okey.c_str());
+#endif
+ switch(method) {
+ //case OA_RSA:
+ // sign = oauth_sign_rsa_sha1(odat.c_str(), okey.c_str()); // XXX okey needs to be RSA key!
+ // break;
+ case OA_PLAINTEXT:
+ sign = oauth_sign_plaintext(odat.c_str(), okey.c_str()).c_str();
+ break;
+ default:
+ sign = oauth_sign_hmac_sha1(odat.c_str(), okey.c_str());
+ break;
+ }
+
+ // append signature to query args.
+ snprintf(oarg, 1024, "oauth_signature=%s",sign.c_str());
+ argvp->push_back(oarg);
+}
+
+std::string oauth_sign_array2(
+ std::vector<std::string> *argvp,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+)
+{
+
+ std::string result;
+ oauth_sign_array2_process(argvp, postargs, method, http_method, c_key, c_sec, t_key, t_sec);
+
+ // build URL params
+ result = oauth_serialize_url(*argvp, (postargs?1:0));
+
+ if (postargs) {
+ *postargs = result;
+ result = argvp->at(0);
+ }
+
+ return result;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/twicpps/oauth.h Wed Jul 08 03:52:54 2015 +0000
@@ -0,0 +1,503 @@
+/**
+ * @brief OAuth.net implementation in POSIX-C.
+ * @file oauth.h
+ * @author Robin Gareus <robin@gareus.org>
+ *
+ * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#ifndef _OAUTH_H
+#define _OAUTH_H 1
+
+#include <vector>
+#include <string>
+
+#ifndef DOXYGEN_IGNORE
+// liboauth version
+#define LIBOAUTH_VERSION "0.8.9"
+#define LIBOAUTH_VERSION_MAJOR 0
+#define LIBOAUTH_VERSION_MINOR 8
+#define LIBOAUTH_VERSION_MICRO 9
+
+//interface revision number
+//http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+#define LIBOAUTH_CUR 7
+#define LIBOAUTH_REV 0
+#define LIBOAUTH_AGE 7
+#endif
+
+#ifdef __GNUC__
+# define OA_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
+#else
+# define OA_GCC_VERSION_AT_LEAST(x,y) 0
+#endif
+
+#ifndef attribute_deprecated
+#if OA_GCC_VERSION_AT_LEAST(3,1)
+# define attribute_deprecated __attribute__((deprecated))
+#else
+# define attribute_deprecated
+#endif
+#endif
+
+/** \enum OAuthMethod
+ * signature method to used for signing the request.
+ */
+typedef enum {
+ OA_HMAC=0, ///< use HMAC-SHA1 request signing method
+ OA_RSA, ///< use RSA signature
+ OA_PLAINTEXT ///< use plain text signature (for testing only)
+ } OAuthMethod;
+
+/**
+ * Base64 encode and return size data in 'src'. The caller must free the
+ * returned string.
+ *
+ * @param size The size of the data in src
+ * @param src The data to be base64 encode
+ * @return encoded string otherwise NULL
+ */
+std::string oauth_encode_base64(const unsigned char *src, int size);
+
+/**
+ * Decode the base64 encoded string 'src' into the memory pointed to by
+ * 'dest'.
+ *
+ * @param dest Pointer to memory for holding the decoded string.
+ * Must be large enough to receive the decoded string.
+ * @param src A base64 encoded string.
+ * @return the length of the decoded string if decode
+ * succeeded otherwise 0.
+ */
+std::string oauth_decode_base64(const char *src);
+
+/**
+ * Escape 'string' according to RFC3986 and
+ * http://oauth.net/core/1.0/#encoding_parameters.
+ *
+ * @param string The data to be encoded
+ * @return encoded string otherwise NULL
+ * The caller must free the returned string.
+ */
+std::string oauth_url_escape(const char *string);
+
+/**
+ * Parse RFC3986 encoded 'string' back to unescaped version.
+ *
+ * @param string The data to be unescaped
+ * @param olen unless NULL the length of the returned string is stored there.
+ * @return decoded string or NULL
+ * The caller must free the returned string.
+ */
+std::string oauth_url_unescape(const char *string);
+
+
+/**
+ * returns base64 encoded HMAC-SHA1 signature for
+ * given message and key.
+ * both data and key need to be urlencoded.
+ *
+ * the returned string needs to be freed by the caller
+ *
+ * @param m message to be signed
+ * @param k key used for signing
+ * @return signature string.
+ */
+std::string oauth_sign_hmac_sha1 (const char *m, const char *k);
+
+/**
+ * same as \ref oauth_sign_hmac_sha1 but allows
+ * to specify length of message and key (in case they contain null chars).
+ *
+ * @param m message to be signed
+ * @param ml length of message
+ * @param k key used for signing
+ * @param kl length of key
+ * @return signature string.
+ */
+std::string oauth_sign_hmac_sha1_raw(const char *m, const size_t ml, const char *k, const size_t kl);
+
+/**
+ * returns plaintext signature for the given key.
+ *
+ * the returned string needs to be freed by the caller
+ *
+ * @param m message to be signed
+ * @param k key used for signing
+ * @return signature string
+ */
+std::string oauth_sign_plaintext(const char *m, const char *k);
+
+/**
+ * returns RSA-SHA1 signature for given data.
+ * the returned signature needs to be freed by the caller.
+ *
+ * @param m message to be signed
+ * @param k private-key PKCS and Base64-encoded
+ * @return base64 encoded signature string.
+ */
+//std::string oauth_sign_rsa_sha1 (const char *m, const char *k);
+
+/**
+ * verify RSA-SHA1 signature.
+ *
+ * returns the output of EVP_VerifyFinal() for a given message,
+ * cert/pubkey and signature.
+ *
+ * @param m message to be verified
+ * @param c public-key or x509 certificate
+ * @param s base64 encoded signature
+ * @return 1 for a correct signature, 0 for failure and -1 if some other error occurred
+ */
+int oauth_verify_rsa_sha1(const char *m, const char *c, const char *s);
+
+/**
+ * url-escape strings and concatenate with '&' separator.
+ * The number of strings to be concatenated must be
+ * given as first argument.
+ * all arguments thereafter must be of type (char *)
+ *
+ * @param len the number of arguments to follow this parameter
+ *
+ * @return pointer to memory holding the concatenated
+ * strings - needs to be free(d) by the caller. or NULL
+ * in case we ran out of memory.
+ */
+std::string oauth_catenc(int len, ...);
+
+/**
+ * splits the given url into a parameter array.
+ * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
+ * (see \ref oauth_split_post_paramters for a more generic version)
+ *
+ * @param url the url or query-string to parse; may be NULL
+ * @param argv pointer to a (char *) array where the results are stored.
+ * The array is re-allocated to match the number of parameters and each
+ * parameter-string is allocated with strdup. - The memory needs to be freed
+ * by the caller.
+ *
+ * @return number of parameter(s) in array.
+ */
+void oauth_split_url_parameters(const char *url, char ***argv);
+
+/**
+ * splits the given url into a parameter array.
+ * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
+ *
+ * @param url the url or query-string to parse.
+ * @param argv pointer to a (char *) array where the results are stored.
+ * The array is re-allocated to match the number of parameters and each
+ * parameter-string is allocated with strdup. - The memory needs to be freed
+ * by the caller.
+ * @param qesc use query parameter escape (vs post-param-escape) - if set
+ * to 1 all '+' are treated as spaces ' '
+ *
+ * @return number of parameter(s) in array.
+ */
+void oauth_split_post_paramters(const char *url, char ***argv, short qesc);
+
+/**
+ * build a url query string from an array.
+ *
+ * @param argc the total number of elements in the array
+ * @param start element in the array at which to start concatenating.
+ * @param argv parameter-array to concatenate.
+ * @return url string needs to be freed by the caller.
+ *
+ */
+std::string oauth_serialize_url (std::vector<std::string> const &argv, int start);
+
+/**
+ * encode query parameters from an array.
+ *
+ * @param argc the total number of elements in the array
+ * @param start element in the array at which to start concatenating.
+ * @param argv parameter-array to concatenate.
+ * @param sep separator for parameters (usually "&")
+ * @param mod - bitwise modifiers:
+ * 1: skip all values that start with "oauth_"
+ * 2: skip all values that don't start with "oauth_"
+ * 4: double quotation marks are added around values (use with sep ", " for HTTP Authorization header).
+ * @return url string needs to be freed by the caller.
+ */
+std::string oauth_serialize_url_sep (std::vector<std::string> const &argv, int start, char const *sep, int mod);
+
+/**
+ * build a query parameter string from an array.
+ *
+ * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv).
+ * It strips the leading host/path, which is usually the first
+ * element when using oauth_split_url_parameters on an URL.
+ *
+ * @param argc the total number of elements in the array
+ * @param argv parameter-array to concatenate.
+ * @return url string needs to be freed by the caller.
+ */
+std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv);
+
+/**
+ * generate a random string between 15 and 32 chars length
+ * and return a pointer to it. The value needs to be freed by the
+ * caller
+ *
+ * @return zero terminated random string.
+ */
+std::string oauth_gen_nonce();
+
+/**
+ * string compare function for oauth parameters.
+ *
+ * used with qsort. needed to normalize request parameters.
+ * see http://oauth.net/core/1.0/#anchor14
+ */
+int oauth_cmpstringp(const void *p1, const void *p2);
+
+
+/**
+ * search array for parameter key.
+ * @param argv length of array to search
+ * @param argc parameter array to search
+ * @param key key of parameter to check.
+ *
+ * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise.
+ */
+bool oauth_param_exists(std::vector<std::string> const &argv, char const *key);
+
+/**
+ * free array args
+ *
+ * @param argcp pointer to array length int
+ * @param argvp pointer to array values to be free()d
+ */
+void oauth_free_array(int *argcp, std::vector<std::string> *argvp);
+
+/**
+ * calculate OAuth-signature for a given HTTP request URL, parameters and oauth-tokens.
+ *
+ * if 'postargs' is NULL a "GET" request is signed and the
+ * signed URL is returned. Else this fn will modify 'postargs'
+ * to point to memory that contains the signed POST-variables
+ * and returns the base URL.
+ *
+ * both, the return value and (if given) 'postargs' need to be freed
+ * by the caller.
+ *
+ * @param url The request URL to be signed. append all GET or POST
+ * query-parameters separated by either '?' or '&' to this parameter.
+ *
+ * @param postargs This parameter points to an area where the return value
+ * is stored. If 'postargs' is NULL, no value is stored.
+ *
+ * @param method specify the signature method to use. It is of type
+ * \ref OAuthMethod and most likely \ref OA_HMAC.
+ *
+ * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
+ * If NULL is given as 'http_method' this defaults to "GET" when
+ * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
+ *
+ * @param c_key consumer key
+ * @param c_sec consumer secret
+ * @param t_key token key
+ * @param t_sec token secret
+ *
+ * @return the signed url or NULL if an error occurred.
+ *
+ */
+std::string oauth_sign_url2 (const char *url, std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+ );
+
+/**
+ * @deprecated Use oauth_sign_url2() instead.
+ */
+std::string oauth_sign_url (const char *url, std::string *postargs,
+ OAuthMethod method,
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+ ) attribute_deprecated;
+
+
+/**
+ * the back-end behind by /ref oauth_sign_array2.
+ * however it does not serialize the signed URL again.
+ * The user needs to call /ref oauth_serialize_url (oA)
+ * and /ref oauth_free_array to do so.
+ *
+ * This allows to split parts of the URL to be used for
+ * OAuth HTTP Authorization header:
+ * see http://oauth.net/core/1.0a/#consumer_req_param
+ * the oauthtest2 example code does so.
+ *
+ *
+ * @param argcp pointer to array length int
+ * @param argvp pointer to array values
+ * (argv[0]="http://example.org:80/" argv[1]="first=QueryParamater" ..
+ * the array is modified: fi. oauth_ parameters are added)
+ * These arrays can be generated with /ref oauth_split_url_parameters
+ * or /ref oauth_split_post_paramters.
+ *
+ * @param postargs This parameter points to an area where the return value
+ * is stored. If 'postargs' is NULL, no value is stored.
+ *
+ * @param method specify the signature method to use. It is of type
+ * \ref OAuthMethod and most likely \ref OA_HMAC.
+ *
+ * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
+ * If NULL is given as 'http_method' this defaults to "GET" when
+ * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
+ *
+ * @param c_key consumer key
+ * @param c_sec consumer secret
+ * @param t_key token key
+ * @param t_sec token secret
+ *
+ * @return void
+ *
+ */
+void oauth_sign_array2_process (std::vector<std::string> *argvp,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+ );
+
+/**
+ * same as /ref oauth_sign_url
+ * with the url already split into parameter array
+ *
+ * @param argcp pointer to array length int
+ * @param argvp pointer to array values
+ * (argv[0]="http://example.org:80/" argv[1]="first=QueryParamater" ..
+ * the array is modified: fi. oauth_ parameters are added)
+ * These arrays can be generated with /ref oauth_split_url_parameters
+ * or /ref oauth_split_post_paramters.
+ *
+ * @param postargs This parameter points to an area where the return value
+ * is stored. If 'postargs' is NULL, no value is stored.
+ *
+ * @param method specify the signature method to use. It is of type
+ * \ref OAuthMethod and most likely \ref OA_HMAC.
+ *
+ * @param http_method The HTTP request method to use (ie "GET", "PUT",..)
+ * If NULL is given as 'http_method' this defaults to "GET" when
+ * 'postargs' is also NULL and when postargs is not NULL "POST" is used.
+ *
+ * @param c_key consumer key
+ * @param c_sec consumer secret
+ * @param t_key token key
+ * @param t_sec token secret
+ *
+ * @return the signed url or NULL if an error occurred.
+ */
+std::string oauth_sign_array2 (std::vector<std::string> *argvp,
+ std::string *postargs,
+ OAuthMethod method,
+ const char *http_method, //< HTTP request method
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+ );
+
+/**
+ * @deprecated Use oauth_sign_array2() instead.
+ */
+char *oauth_sign_array(
+ std::vector<std::string> *argvp,
+ char **postargs,
+ OAuthMethod method,
+ const char *c_key, //< consumer key - posted plain text
+ const char *c_sec, //< consumer secret - used as 1st part of secret-key
+ const char *t_key, //< token key - posted plain text in URL
+ const char *t_sec //< token secret - used as 2st part of secret-key
+ ) attribute_deprecated;
+
+/**
+ * do a HTTP GET request, wait for it to finish
+ * and return the content of the reply.
+ * (requires libcurl or a command-line HTTP client)
+ *
+ * If compiled <b>without</b> libcurl this function calls
+ * a command-line executable defined in the environment variable
+ * OAUTH_HTTP_GET_CMD - it defaults to
+ * <tt>curl -sA 'liboauth-agent/0.1' '%%u'</tt>
+ * where %%u is replaced with the URL and query parameters.
+ *
+ * bash & wget example:
+ * <tt>export OAUTH_HTTP_CMD="wget -q -U 'liboauth-agent/0.1' '%u' "</tt>
+ *
+ * WARNING: this is a tentative function. it's convenient and handy for testing
+ * or developing OAuth code. But don't rely on this function
+ * to become a stable part of this API. It does not do
+ * much error checking or handling for one thing..
+ *
+ * NOTE: \a u and \a q are just concatenated with a '?' in between,
+ * unless \a q is NULL. in which case only \a u will be used.
+ *
+ * @param u base url to get
+ * @param q query string to send along with the HTTP request or NULL.
+ * @return In case of an error NULL is returned; otherwise a pointer to the
+ * replied content from HTTP server. latter needs to be freed by caller.
+ */
+std::string oauth_http_get_(const char *u, const char *q);
+
+/**
+ * do a HTTP POST request, wait for it to finish
+ * and return the content of the reply.
+ * (requires libcurl or a command-line HTTP client)
+ *
+ * If compiled <b>without</b> libcurl this function calls
+ * a command-line executable defined in the environment variable
+ * OAUTH_HTTP_CMD - it defaults to
+ * <tt>curl -sA 'liboauth-agent/0.1' -d '%%p' '%%u'</tt>
+ * where %%p is replaced with the postargs and %%u is replaced with
+ * the URL.
+ *
+ * bash & wget example:
+ * <tt>export OAUTH_HTTP_CMD="wget -q -U 'liboauth-agent/0.1' --post-data='%p' '%u' "</tt>
+ *
+ * NOTE: This function uses the curl's default HTTP-POST Content-Type:
+ * application/x-www-form-urlencoded which is the only option allowed
+ * by oauth core 1.0 spec. Experimental code can use the Environment variable
+ * to transmit custom HTTP headers or parameters.
+ *
+ * WARNING: this is a tentative function. it's convenient and handy for testing
+ * or developing OAuth code. But don't rely on this function
+ * to become a stable part of this API. It does not do
+ * much error checking for one thing..
+ *
+ * @param u url to query
+ * @param p postargs to send along with the HTTP request.
+ * @return replied content from HTTP server. needs to be freed by caller.
+ */
+std::string oauth_http_post_(const char *u, const char *p);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/twicpps/sha1.c Wed Jul 08 03:52:54 2015 +0000
@@ -0,0 +1,386 @@
+/*
+ * sha1.c
+ *
+ * Description:
+ * This file implements the Secure Hashing Algorithm 1 as
+ * defined in FIPS PUB 180-1 published April 17, 1995.
+ *
+ * The SHA-1, produces a 160-bit message digest for a given
+ * data stream. It should take about 2**n steps to find a
+ * message with the same digest as a given message and
+ * 2**(n/2) to find any two messages with the same digest,
+ * when n is the digest size in bits. Therefore, this
+ * algorithm can serve as a means of providing a
+ * "fingerprint" for a message.
+ *
+ * Portability Issues:
+ * SHA-1 is defined in terms of 32-bit "words". This code
+ * uses <stdint.h> (included via "sha1.h" to define 32 and 8
+ * bit unsigned integer types. If your C compiler does not
+ * support 32 bit unsigned integers, this code is not
+ * appropriate.
+ *
+ * Caveats:
+ * SHA-1 is designed to work with messages less than 2^64 bits
+ * long. Although SHA-1 allows a message digest to be generated
+ * for messages of any number of bits less than 2^64, this
+ * implementation only works with messages with a length that is
+ * a multiple of the size of an 8-bit character.
+ *
+ */
+
+#include "sha1.h"
+
+#pragma warning(disable:4244)
+
+/*
+ * Define the SHA1 circular left shift macro
+ */
+#define SHA1CircularShift(bits,word) \
+ (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/* Local Function Prototyptes */
+void SHA1PadMessage(SHA1Context *);
+void SHA1ProcessMessageBlock(SHA1Context *);
+
+/*
+ * SHA1Reset
+ *
+ * Description:
+ * This function will initialize the SHA1Context in preparation
+ * for computing a new SHA1 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Reset(SHA1Context *context)
+{
+ if (!context)
+ {
+ return shaNull;
+ }
+
+ context->Length_Low = 0;
+ context->Length_High = 0;
+ context->Message_Block_Index = 0;
+
+ context->Intermediate_Hash[0] = 0x67452301;
+ context->Intermediate_Hash[1] = 0xEFCDAB89;
+ context->Intermediate_Hash[2] = 0x98BADCFE;
+ context->Intermediate_Hash[3] = 0x10325476;
+ context->Intermediate_Hash[4] = 0xC3D2E1F0;
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1Result
+ *
+ * Description:
+ * This function will return the 160-bit message digest into the
+ * Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 19th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA-1 hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Result( SHA1Context *context,
+ uint8_t Message_Digest[SHA1HashSize])
+{
+ int i;
+
+ if (!context || !Message_Digest)
+ {
+ return shaNull;
+ }
+
+ if (context->Corrupted)
+ {
+ return context->Corrupted;
+ }
+
+ if (!context->Computed)
+ {
+ SHA1PadMessage(context);
+ for(i=0; i<64; ++i)
+ {
+ /* message may be sensitive, clear it out */
+ context->Message_Block[i] = 0;
+ }
+ context->Length_Low = 0; /* and clear length */
+ context->Length_High = 0;
+ context->Computed = 1;
+ }
+
+ for(i = 0; i < SHA1HashSize; ++i)
+ {
+ Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
+ }
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Input( SHA1Context *context,
+ const uint8_t *message_array,
+ unsigned length)
+{
+ if (!length)
+ {
+ return shaSuccess;
+ }
+
+ if (!context || !message_array)
+ {
+ return shaNull;
+ }
+
+ if (context->Computed)
+ {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+ {
+ return context->Corrupted;
+ }
+ while(length-- && !context->Corrupted)
+ {
+ context->Message_Block[context->Message_Block_Index++] =
+ (*message_array & 0xFF);
+
+ context->Length_Low += 8;
+ if (context->Length_Low == 0)
+ {
+ context->Length_High++;
+ if (context->Length_High == 0)
+ {
+ /* Message is too long */
+ context->Corrupted = 1;
+ }
+ }
+
+ if (context->Message_Block_Index == 64)
+ {
+ SHA1ProcessMessageBlock(context);
+ }
+
+ message_array++;
+ }
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1ProcessMessageBlock
+ *
+ * Description:
+ * This function will process the next 512 bits of the message
+ * stored in the Message_Block array.
+ *
+ * Parameters:
+ * None.
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the
+ * names used in the publication.
+ *
+ *
+ */
+void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+ const uint32_t K[] = { /* Constants defined in SHA-1 */
+ 0x5A827999,
+ 0x6ED9EBA1,
+ 0x8F1BBCDC,
+ 0xCA62C1D6
+ };
+ int t; /* Loop counter */
+ uint32_t temp; /* Temporary word value */
+ uint32_t W[80]; /* Word sequence */
+ uint32_t A, B, C, D, E; /* Word buffers */
+
+ /*
+ * Initialize the first 16 words in the array W
+ */
+ for(t = 0; t < 16; t++)
+ {
+ W[t] = context->Message_Block[t * 4] << 24;
+ W[t] |= context->Message_Block[t * 4 + 1] << 16;
+ W[t] |= context->Message_Block[t * 4 + 2] << 8;
+ W[t] |= context->Message_Block[t * 4 + 3];
+ }
+
+ for(t = 16; t < 80; t++)
+ {
+ W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+
+ for(t = 0; t < 20; t++)
+ {
+ temp = SHA1CircularShift(5,A) +
+ ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 20; t < 40; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 40; t < 60; t++)
+ {
+ temp = SHA1CircularShift(5,A) +
+ ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 60; t < 80; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+
+ context->Message_Block_Index = 0;
+}
+
+
+/*
+ * SHA1PadMessage
+ *
+ * Description:
+ * According to the standard, the message must be padded to an even
+ * 512 bits. The first padding bit must be a '1'. The last 64
+ * bits represent the length of the original message. All bits in
+ * between should be 0. This function will pad the message
+ * according to those rules by filling the Message_Block array
+ * accordingly. It will also call the ProcessMessageBlock function
+ * provided appropriately. When it returns, it can be assumed that
+ * the message digest has been computed.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to pad
+ * ProcessMessageBlock: [in]
+ * The appropriate SHA*ProcessMessageBlock function
+ * Returns:
+ * Nothing.
+ *
+ */
+
+void SHA1PadMessage(SHA1Context *context)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ if (context->Message_Block_Index > 55)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0x80;
+ while(context->Message_Block_Index < 64)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+
+ SHA1ProcessMessageBlock(context);
+
+ while(context->Message_Block_Index < 56)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+ }
+ else
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0x80;
+ while(context->Message_Block_Index < 56)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+ }
+
+ /*
+ * Store the message length as the last 8 octets
+ */
+ context->Message_Block[56] = context->Length_High >> 24;
+ context->Message_Block[57] = context->Length_High >> 16;
+ context->Message_Block[58] = context->Length_High >> 8;
+ context->Message_Block[59] = context->Length_High;
+ context->Message_Block[60] = context->Length_Low >> 24;
+ context->Message_Block[61] = context->Length_Low >> 16;
+ context->Message_Block[62] = context->Length_Low >> 8;
+ context->Message_Block[63] = context->Length_Low;
+
+ SHA1ProcessMessageBlock(context);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/twicpps/sha1.h Wed Jul 08 03:52:54 2015 +0000
@@ -0,0 +1,85 @@
+/*
+ * sha1.h
+ *
+ * Description:
+ * This is the header file for code which implements the Secure
+ * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ * April 17, 1995.
+ *
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the names
+ * used in the publication.
+ *
+ * Please read the file sha1.c for more information.
+ *
+ */
+
+#ifndef _SHA1_H_
+#define _SHA1_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#include <stdint.h>
+typedef unsigned long uint32_t;
+typedef int int_least16_t;
+typedef unsigned char uint8_t;
+
+/*
+ * If you do not have the ISO standard stdint.h header file, then you
+ * must typdef the following:
+ * name meaning
+ * uint32_t unsigned 32 bit integer
+ * uint8_t unsigned 8 bit integer (i.e., unsigned char)
+ * int_least16_t integer of >= 16 bits
+ *
+ */
+
+#ifndef _SHA_enum_
+#define _SHA_enum_
+enum
+{
+ shaSuccess = 0,
+ shaNull, /* Null pointer parameter */
+ shaInputTooLong, /* input data too long */
+ shaStateError /* called Input after Result */
+};
+#endif
+#define SHA1HashSize 20
+
+/*
+ * This structure will hold context information for the SHA-1
+ * hashing operation
+ */
+typedef struct SHA1Context
+{
+ uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */
+
+ uint32_t Length_Low; /* Message length in bits */
+ uint32_t Length_High; /* Message length in bits */
+
+ /* Index into message block array */
+ int_least16_t Message_Block_Index;
+ uint8_t Message_Block[64]; /* 512-bit message blocks */
+
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the message digest corrupted? */
+} SHA1Context;
+
+/*
+ * Function Prototypes
+ */
+
+int SHA1Reset( SHA1Context *);
+int SHA1Input( SHA1Context *,
+ const uint8_t *,
+ unsigned int);
+int SHA1Result( SHA1Context *,
+ uint8_t Message_Digest[SHA1HashSize]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
ban4jp -
