/**
 * Sign the parameters
 * 
 * @param sdb the SimpleDB handle
 * @param params the parameter array
 * @param buffer the buffer to write the signature to (must be at least EVP_MAX_MD_SIZE * 2 bytes)
 * @param plen the pointer to the place to store the length of the signature (can be NULL)
 * @return SDB_OK if no errors occurred
 */
int sdb_params_sign(struct SDB* sdb, struct sdb_params* params, char* buffer, size_t* plen)
{
	assert(params->size >= 2);
	
	
	// Signature version 0
	
	if (sdb->sdb_signature_ver == 0) {
	
		assert(strcmp(params->params[0].key, "Action") == 0);
		assert(strcmp(params->params[1].key, "Timestamp") == 0);
		
		size_t l = strlen(params->params[0].value) + strlen(params->params[1].value) + 4;
		char* b = (char*) alloca(l);
		
		strcpy(b, params->params[0].value);
		strcat(b, params->params[1].value);
		
		return sdb_sign(sdb, b, buffer, plen); 
	}
	
	
	// Signature version 1
	
	if (sdb->sdb_signature_ver == 1) {
		
		SDB_SAFE(sdb_params_sort(params));
		
		size_t i, l = 0;
		for (i = 0; i < params->size; i++) {
			l += strlen(params->params[i].key);
			l += strlen(params->params[i].value);
		}
		
		char* b = (char*) alloca(l);
		*b = '\0';
		
		for (i = 0; i < params->size; i++) {
			strcat(b, params->params[i].key);
			strcat(b, params->params[i].value);
		}
		
		return sdb_sign(sdb, b, buffer, plen); 
	}
	
	
	return SDB_E_INVALID_SIGNATURE_VER;
}
Esempio n. 2
0
/**
 * Create the URL-encoded parameters string with SignatureVersion 2 sig.
 * 
 * @param sdb the SimpleDB handle
 * @param params the parameter array
 * @param pbuffer the variable for the output buffer (will be allocated by the routine, but has to be freed by caller)
 * @return SDB_OK if no errors occurred
 */
int sdb_params_export(struct SDB* sdb, struct sdb_params* params, char** pbuffer)
{
	assert(params->size >= 2);
	
	// Sign the parameters
	
	char signature[EVP_MAX_MD_SIZE * 2];
	
	// Determine the appropriate size
	
	size_t i, l = 0;
	for (i = 0; i < params->size; i++) {
		l += strlen(params->params[i].key) + 1;
		l += strlen(params->params[i].value) * 3 + 1;
	}
	
	// Allocate buffer
	
	*pbuffer = (char*) malloc(l + 4);
	char* b = *pbuffer;
	*b = '\0';
	
	// Build the string
	
	SDB_SAFE(sdb_params_sort(params));
	for (i = 0; i < params->size; i++) {
	
		if (i > 0) strcat(b, "&");
		
		strcat(b, params->params[i].key);
		strcat(b, "=");
		
		char* e = sdb_escape(sdb, params->params[i].value, strlen(params->params[i].value));
		if (e == NULL) {
			free(b);
			*pbuffer = NULL;
			return SDB_E_URL_ENCODE_FAILED;
		} 
		
		strcat(b, e);
		curl_free(e);
	}
	
	// string is built, now build complete string to sign
	
	l = strlen(b) + 25;
	char* s = (char*) alloca(l);
	*s = '\0';
	
	strcat(s, "POST\n");
	strcat(s, "sdb.amazonaws.com\n");
	strcat(s, "/\n");
	strcat(s, b);
	
	// Create the signature and add it to the URL-encoded param string
	
	SDB_SAFE(sdb_sign(sdb, s, signature, NULL));
	
	strcat(b, "&Signature=");
	char* e = sdb_escape(sdb->curl_handle, signature, strlen(signature));
	if (e == NULL) {
		free(b);
		*pbuffer = NULL;
		return SDB_E_URL_ENCODE_FAILED;
	}
	strcat(b, e);
	free(e);
	
	return SDB_OK;
}