Пример #1
0
def api_upload(service, encData, encMeta, keys):
    '''
       Uploads data to Send.
       Caution! Data is uploaded as given, this function will not encrypt it for you
    '''
    service += 'api/upload'
    files = requests_toolbelt.MultipartEncoder(
        fields={'file': ('blob', encData, 'application/octet-stream')})
    pbar = progbar(files.len)
    monitor = requests_toolbelt.MultipartEncoderMonitor(
        files, lambda files: pbar.update(monitor.bytes_read - pbar.n))

    headers = {
        'X-File-Metadata': unpadded_urlsafe_b64encode(encMeta),
        'Authorization': 'send-v1 ' + unpadded_urlsafe_b64encode(keys.authKey),
        'Content-type': monitor.content_type
    }

    r = requests.post(service, data=monitor, headers=headers, stream=True)
    r.raise_for_status()
    pbar.close()

    body_json = r.json()
    secretUrl = body_json['url'] + '#' + unpadded_urlsafe_b64encode(
        keys.secretKey)
    fileId = body_json['id']
    fileNonce = unpadded_urlsafe_b64decode(
        r.headers['WWW-Authenticate'].replace('send-v1 ', ''))
    delete_token = body_json['delete']
    return secretUrl, fileId, fileNonce, delete_token
Пример #2
0
def set_password(service, keys, url, fileId, password, nonce):
    ''' sets the download password by sending a HMAC key derived from it to the Send server'''
    service += 'api/password/' + str(fileId)

    sig = sign_nonce(keys.authKey, nonce)
    newAuthKey = keys.deriveNewAuthKey(password, url)

    headers = {'Authorization': 'send-v1 ' + unpadded_urlsafe_b64encode(sig)}
    r = requests.post(service,
                      json={'auth': unpadded_urlsafe_b64encode(newAuthKey)},
                      headers=headers)
    r.raise_for_status()
Пример #3
0
def api_metadata(service, fileId, authorisation):
    headers = {'Authorization' : 'send-v1 ' + unpadded_urlsafe_b64encode(authorisation)}
    url = service + 'api/metadata/' + fileId
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    newNonce = unpadded_urlsafe_b64decode(response.headers['WWW-Authenticate'].replace('send-v1 ', ''))
    return response.json(), newNonce
Пример #4
0
def encrypt_metadata(keys, fileName, fileType='application/octet-stream'):
    '''Encrypt file metadata with the same method as the Send browser/js client'''
    metadata = json.dumps(
        {
            'iv': unpadded_urlsafe_b64encode(keys.encryptIV),
            'name': fileName,
            'type': fileType
        },
        sort_keys=True)

    cipher = Cryptodome.Cipher.AES.new(keys.metaKey,
                                       Cryptodome.Cipher.AES.MODE_GCM,
                                       keys.metaIV)
    encMeta, gcmTag = cipher.encrypt_and_digest(metadata.encode())

    # WebcryptoAPI expects the gcm tag at the end of the ciphertext, return them concatenated
    return encMeta + gcmTag
Пример #5
0
def api_download(service, fileId, authorisation):
    '''Given a Send url, download and return the encrypted data and metadata'''
    data = tempfile.SpooledTemporaryFile(max_size=SPOOL_SIZE, mode='w+b')

    headers = {'Authorization' : 'send-v1 ' + unpadded_urlsafe_b64encode(authorisation)}
    url = service + 'api/download/' + fileId

    r = requests.get(url, headers=headers, stream=True)
    r.raise_for_status()
    content_length = int(r.headers['Content-length'])

    pbar = progbar(content_length)
    for chunk in r.iter_content(chunk_size=CHUNK_SIZE):
        data.write(chunk)
        pbar.update(len(chunk))
    pbar.close()

    data.seek(0)
    return data
Пример #6
0
def test_unpadded_urlsafe_b64encode():
    key = b'\xdf\xd1\x0b\xed+\xaa\xc1cX{\x82\x12\x97c4\xea'
    assert unpadded_urlsafe_b64encode(key) == '39EL7SuqwWNYe4ISl2M06g'