Ejemplo n.º 1
0
char * build_signature(const char * method, const char * path, const struct curl_slist *headers, const char * secret) {
  int signature_length = 0;
  char * data = canonical_string(method, path, headers);
  debug("cs = '%s'", data);
  char *signature = hmac(secret, data, &signature_length);
  char *base64_sig = base64(signature, signature_length);
  
  free(data);
  free(signature);
  
  return base64_sig;
}
Ejemplo n.º 2
0
bool verify_mutable_item(
	span<char const> v
	, span<char const> salt
	, sequence_number const seq
	, public_key const& pk
	, signature const& sig)
{
	char str[1200];
	int len = canonical_string(v, seq, salt, str);

	return ed25519_verify(sig, {str, size_t(len)}, pk);
}
Ejemplo n.º 3
0
// given the bencoded buffer ``v``, the salt (which is optional and may have
// a length of zero to be omitted), sequence number ``seq``, public key (32
// bytes ed25519 key) ``pk`` and a secret/private key ``sk`` (64 bytes ed25519
// key) a signature ``sig`` is produced. The ``sig`` pointer must point to
// at least 64 bytes of available space. This space is where the signature is
// written.
signature sign_mutable_item(
	span<char const> v
	, span<char const> salt
	, sequence_number const seq
	, public_key const& pk
	, secret_key const& sk)
{
	char str[1200];
	int const len = canonical_string(v, seq, salt, str);

	return ed25519_sign({str, size_t(len)}, pk, sk);
}
Ejemplo n.º 4
0
bool verify_mutable_item(
    std::pair<char const*, int> v,
    std::pair<char const*, int> salt,
    boost::uint64_t seq,
    char const* pk,
    char const* sig)
{
#ifdef TORRENT_USE_VALGRIND
    VALGRIND_CHECK_MEM_IS_DEFINED(v.first, v.second);
    VALGRIND_CHECK_MEM_IS_DEFINED(pk, item_pk_len);
    VALGRIND_CHECK_MEM_IS_DEFINED(sig, item_sig_len);
#endif

    char str[canonical_length];
    int len = canonical_string(v, seq, salt, str);

    return ed25519_verify((unsigned char const*)sig,
                          (unsigned char const*)str,
                          len,
                          (unsigned char const*)pk) == 1;
}
Ejemplo n.º 5
0
class response_buffer *request(string method,string path,string query,time_t expires,
			       const char *sendbuf,size_t sendbuflen,
			       const s3headers *extraheaders)
{
    /* Note: this function is not threadsafe */
    static bool curl_initted = false;
    if(!curl_initted){
	curl_global_init(CURL_GLOBAL_ALL);	
	curl_initted=true;
    }

    int retry_count=0;
    class response_buffer *b = 0;
    class buffer *h = 0;
    do {

	if(s3_debug>1) printf("==================================================\n");
	if(s3_debug && retry_count>0) printf("=== S3 RETRY %d ===\n",retry_count);
	
	CURL *c = curl_easy_init();
	struct curl_slist *headers=NULL;

	if(expires==0){
	    /* Add the Date: field to the header */
	    struct tm tm;
	    time_t t = time(0);
	    char date[64];
	    strftime(date,sizeof(date),"Date: %a, %d %b %Y %X GMT",gmtime_r(&t,&tm));
	    headers = curl_slist_append(headers, date);
	}

	/* Add the extra headers */
	while(extraheaders  && extraheaders[0].name){
	    int len = strlen(extraheaders[0].name)+strlen(extraheaders[0].value)+4;
	    char *buf = (char *)alloca(len);
	    snprintf(buf,len,"%s: %s",extraheaders[0].name,extraheaders[0].value);
	    headers = curl_slist_append(headers, buf);
	    extraheaders++;
	}

	string url = aws_base_url + path;
	string canonical_str     = canonical_string(method,path,headers,expires);
	string encoded_canonical = encode(aws_secret_access_key,canonical_str);

	if(expires==0){
	    /* Create an Authorization header */

	    char authorization[96];
	
	    snprintf(authorization,sizeof(authorization),"Authorization: AWS %s:%s",
		     aws_access_key_id,encoded_canonical.c_str());
	    headers = curl_slist_append(headers, authorization);
	    curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers);
	}

	if(expires){
	    /* Add authorization to the URL*/
	    if(query.size()>0) query += "&";
	    query += "Signature=" + quote_plus(encoded_canonical);
	    query += "&Expires=" + itos(expires);
	    query += "&AWSAccessKeyId=" + string(aws_access_key_id);
	}

	if(query.size()>0){
	    url += "?" + query;
	}

	if(b) delete b;
	b = new response_buffer();
	memset(b->ETag,0,sizeof(b->ETag));
	if(s3_debug>1) curl_easy_setopt(c,CURLOPT_VERBOSE,1);
	if(method != "GET"){
	    curl_easy_setopt(c,CURLOPT_CUSTOMREQUEST,method.c_str());
	}

	if(method == "HEAD"){
	    curl_easy_setopt(c,CURLOPT_NOBODY,1);
	}

	/* Queries that take longer than an hour should timeout */
	curl_easy_setopt(c,CURLOPT_TIMEOUT,60*60);

	/* Disable DNS cache */
	curl_easy_setopt(c,CURLOPT_DNS_CACHE_TIMEOUT,0); // per amazon specification
	curl_easy_setopt(c,CURLOPT_WRITEFUNCTION,buffer_write);
	curl_easy_setopt(c,CURLOPT_WRITEDATA,b); // fourth argument
	curl_easy_setopt(c,CURLOPT_URL,url.c_str());

	/* Are we sending data */
	class buffer *sendbuffer = 0;
	if(sendbuf){
	    sendbuffer = new buffer(sendbuf,sendbuflen);
	    curl_easy_setopt(c,CURLOPT_READFUNCTION,buffer_read);
	    curl_easy_setopt(c,CURLOPT_READDATA,sendbuffer);
	    curl_easy_setopt(c,CURLOPT_UPLOAD,1);
	    curl_easy_setopt(c,CURLOPT_INFILESIZE,sendbuflen);
	    //fprintf(stderr,"***** sendbuflen= %d %qd\n",sizeof(sendbuflen),sendbuflen);
	}

	/* Make provisions to get the response headers */
	if(h) delete h;
	h = new buffer();
	curl_easy_setopt(c,CURLOPT_HEADERFUNCTION,buffer_write);
	curl_easy_setopt(c,CURLOPT_WRITEHEADER,h); // fourth argument

	/* Make provisions for getting the headers */

	int success = curl_easy_perform(c);

	if(sendbuffer){
	    delete sendbuffer;
	    sendbuffer = 0;
	    if(success==0) s3_bytes_written += sendbuflen;
	}

	s3_bytes_read += h->len;
	s3_bytes_read += b->len;

	// CURL API says do not assume NULL terminate, so terminate it
	h->write("\000",1);			
	curl_easy_getinfo(c,CURLINFO_RESPONSE_CODE,&b->result);

	/* Now clean up */
	s3_request_retry_count = retry_count;
	if(headers) curl_slist_free_all(headers);
	curl_easy_cleanup(c);

	/* Process the results */
	if(success!=0){
	    delete h;
	    delete b;
	    s3_request_retry_count = retry_count;
	    return 0;			// internal CURL error
	}
	if(s3_debug>2){
	    printf("Header results:\n");
	    h->print();
	    printf("Data results:\n");
	    b->print();
	    printf("\n");
	}
    } while(b->result==500 && ++retry_count<s3_retry_max);

    if(b->result==404) errno=ENOENT;

    /* Pull out the headers */
    char *line,*brkt;
    for(line = strtok_r(h->base,"\r\n",&brkt);
	line;
	line = strtok_r(NULL,"\r\n",&brkt)){
	char *cc = strchr(line,':');
	if(cc){
	    *cc++ = '\000';
	    while(*cc && isspace(*cc)) cc++;
	    b->rheaders[line] = cc;
	}
    }

    /* Find the ETag in the header and put in the buffer */
    const char *e = b->rheaders["ETag"].c_str();
    if(strlen(e)==34){
	for(int i=0;i<16;i++){
	    b->ETag[i] = (hexval(e[i*2+1])<<4) + hexval(e[i*2+2]);
	}
    }

    delete h;				// we don't care about it
    if(s3_debug>1) printf(".\n\n");
    return b;
}