diff options
| -rw-r--r-- | shopify.c | 39 | 
1 files changed, 30 insertions, 9 deletions
@@ -8,6 +8,7 @@  #include <curl/curl.h>  #include <json.h>  #include <l8w8jwt/decode.h> +#include <l8w8jwt/base64.h>  #include <microhttpd.h>  #include "shopify.h" @@ -176,6 +177,7 @@ static enum MHD_Result handle_request(void *cls, struct MHD_Connection *con,  	const char *api_key = container->api_key;  	const size_t api_key_len = strlen(api_key);  	const char *api_secret_key = container->api_secret_key; +	const size_t api_secret_key_len = strlen(api_secret_key);  	const char *app_url = container->app_url;  	const size_t app_url_len = strlen(app_url);  	const char *redir_url = container->redir_url; @@ -235,7 +237,7 @@ static enum MHD_Result handle_request(void *cls, struct MHD_Connection *con,  		gcry_mac_hd_t hd;  		gcry_mac_open(&hd, GCRY_MAC_HMAC_SHA256, GCRY_MAC_FLAG_SECURE,  				NULL); -		gcry_mac_setkey(hd, api_secret_key, strlen(api_secret_key)); +		gcry_mac_setkey(hd, api_secret_key, api_secret_key_len);  		gcry_mac_write(hd, query, strlen(query));  		static size_t hex_len = 32;  		unsigned char hex[hex_len]; @@ -318,7 +320,7 @@ static enum MHD_Result handle_request(void *cls, struct MHD_Connection *con,  		params.jwt = (char *)session_token;  		params.jwt_length = strlen(session_token);  		params.verification_key = (unsigned char *)api_secret_key; -		params.verification_key_length = strlen(api_secret_key); +		params.verification_key_length = api_secret_key_len;  		params.validate_exp = 1;  		params.validate_nbf = 1;  		params.validate_aud = (char *)api_key; @@ -329,22 +331,41 @@ static enum MHD_Result handle_request(void *cls, struct MHD_Connection *con,  				&claims_len);  		if (validation != L8W8JWT_NBF_FAILURE)  			printf("JWT payload nbf is invalid.\n"); -		struct l8w8jwt_claim *dest -			= l8w8jwt_get_claim(claims, claims_len, "dest", 4); -		_Bool iss_valid = !strncmp( l8w8jwt_get_claim(claims, -					claims_len, "iss", 3)->value, +		struct l8w8jwt_claim *dest = l8w8jwt_get_claim(claims, +				claims_len, "dest", 4); +		_Bool iss_valid = !strncmp(l8w8jwt_get_claim(claims, claims_len, +					"iss", 3)->value,  				dest->value, dest->value_length);  		printf("JWT payload sub: %s\n", l8w8jwt_get_claim(claims,  					claims_len, "sub", 3)->value);  		l8w8jwt_free_claims(claims, claims_len); -		if (decode != L8W8JWT_SUCCESS -				|| validation != L8W8JWT_VALID +		if (decode != L8W8JWT_SUCCESS || validation != L8W8JWT_VALID  				&& validation != L8W8JWT_NBF_FAILURE  				|| !iss_valid) {  			free(session_token);  			free(shop);  			return MHD_NO;  		} + +		char *last_dot = strrchr(session_token, '.'); +		gcry_mac_hd_t hd; +		gcry_mac_open(&hd, GCRY_MAC_HMAC_SHA256, +				GCRY_MAC_FLAG_SECURE, NULL); +		gcry_mac_setkey(hd, api_secret_key, api_secret_key_len); +		gcry_mac_write(hd, session_token, last_dot - session_token); +		static size_t hmacsha256_len = 32; +		unsigned char hmacsha256[hmacsha256_len]; +		gcry_mac_read(hd, hmacsha256, &hmacsha256_len); +		gcry_mac_close(hd); +		char *sig; +		size_t sig_len; +		l8w8jwt_base64_encode(1, hmacsha256, hmacsha256_len, &sig, +				&sig_len); +		if (strncmp(++last_dot, sig, sig_len)) { +			free(session_token); +			free(shop); +			return MHD_NO; +		}  	}  	char *host = NULL; @@ -398,7 +419,7 @@ static enum MHD_Result handle_request(void *cls, struct MHD_Connection *con,  		static const char *post_tmpl  			= "client_id=%s&client_secret=%s&code=%s";  		char post[strlen(post_tmpl) - strlen("%s") * 3 + strlen(api_key) -			+ strlen(api_secret_key) + strlen(code) + 1]; +			+ api_secret_key_len + strlen(code) + 1];  		sprintf(post, post_tmpl, api_key, api_secret_key, code);  		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);  		curl_easy_perform(curl);  |