예제 #1
0
def test_secretKeys_known_good_keys():
    # test data was obtained by adding debug messages to {"commit":"188b28f","source":"https://github.com/mozilla/send/","version":"v1.2.4"}
    testdata = {
        'secretKey':
        b'q\xd94B\xa1&\x03\xa5<8\xddk\xee.\xea&',
        'encryptKey':
        b'\xc4\x979\xaa\r\n\xeb\xc7\xa16\xa4%\xfd\xa6\x91\t',
        'authKey':
        b'5\xa0@\xef\xd0}f\xc7o{S\x05\xe4,\xe1\xe4\xc2\x8cE\xa1\xfat\xc1\x11\x94e[L\x89%\xf5\x8b\xfc\xb5\x9b\x87\x9a\xf2\xc3\x0eKt\xdeL\xab\xa4\xa6%t\xa6"4\r\x07\xb3\xf5\xf6\xb9\xec\xcc\x08\x80}\xea',
        'metaKey':
        b'\xd5\x9dF\x05\x86\x1a\xfdi\xaeK+\xe7\x8e\x7f\xf2\xfd',
        'password':
        '******',
        'url':
        'http://192.168.254.87:1443/download/fa4cd959de/#cdk0QqEmA6U8ON1r7i7qJg',
        'newAuthKey':
        b'U\x02F\x19\x1b\xc1W\x03q\x86q\xbc\xe7\x84WB\xa7(\x0f\x8a\x0f\x17\\\xb9y\xfaZT\xc1\xbf\xb2\xd48\x82\xa7\t\x9a\xb1\x1e{cg\n\xc6\x995+\x0f\xd3\xf4\xb3kd\x93D\xca\xf9\xa1(\xdf\xcb_^\xa3',
    }
    # generate all keys
    keys = secretKeys(secretKey=testdata['secretKey'],
                      password=testdata['password'],
                      url=testdata['url'])

    # Check every key has the expected value
    assert keys.secretKey == testdata['secretKey']
    assert keys.encryptKey == testdata['encryptKey']
    assert keys.authKey == testdata['authKey']
    assert keys.metaKey == testdata['metaKey']
    assert keys.password == testdata['password']
    assert keys.url == testdata['url']
    assert keys.newAuthKey == testdata['newAuthKey']
예제 #2
0
def send_file(service,
              file,
              fileName=None,
              password=None,
              ignoreVersion=False):

    if checkServerVersion(service, ignoreVersion=ignoreVersion) == False:
        print(
            '\033[1;41m!!! Potentially incompatible server version !!!\033[0m')
    ''' Encrypt & Upload a file to send and return the download URL'''
    fileName = fileName if fileName != None else os.path.basename(file.name)

    print('Encrypting data from "' + fileName + '"')
    keys = secretKeys()
    encData = encrypt_file(file, keys)
    encMeta = encrypt_metadata(keys, fileName)

    print('Uploading "' + fileName + '"')
    secretUrl, fileId, fileNonce, delete_token = api_upload(
        service, encData, encMeta, keys)

    if password != None:
        print('Setting password')
        set_password(service, keys, secretUrl, fileId, password, fileNonce)

    return secretUrl, delete_token
예제 #3
0
def send_urlToFile(url, password=None, ignoreVersion=False):
    service, fileId, key = splitkeyurl(url)

    if checkServerVersion(service, ignoreVersion) == False:
        raise Exception('Potentially incompatible server version, use --ignore-version to disable version checks')

    passwordRequired = check_for_password(service + 'download/' + str(fileId) + '/')

    rawKey = unpadded_urlsafe_b64decode(key)
    if passwordRequired == False and password == None:
        keys = secretKeys(rawKey)
    elif passwordRequired == True and password != None:
        keys = secretKeys(rawKey, password=password, url=url)
        keys.authKey = keys.newAuthKey
    elif passwordRequired and password == None:
        print("A password is required, please enter it now")
        password = getpass.getpass()
        keys = secretKeys(rawKey, password=password, url=url)
        keys.authKey = keys.newAuthKey
    elif passwordRequired == False and password != None:
        raise Exception('A password was provided but none is required')

    print('Checking if file exists...')
    passwordRequired = check_for_password(service + 'download/' + fileId)

    if password == None and passwordRequired == True:
        raise Exception('This Send url requires a password')

    nonce = get_nonce(service + 'download/' + str(fileId) + '/')
    authorisation = sign_nonce(keys.authKey, nonce)
    print('Fetching metadata...')
    jsonMeta, nonce = api_metadata(service, fileId, authorisation)

    encMeta = unpadded_urlsafe_b64decode(jsonMeta['metadata'])
    metadata = decrypt_metadata(encMeta, keys)
    keys.encryptIV = unpadded_urlsafe_b64decode(metadata['iv'])
    print('The file wishes to be called \'' + metadata['name'] + '\' and is ' + str(jsonMeta['size'] - 16) + ' bytes in size')

    print('Downloading ' + url)
    authorisation = sign_nonce(keys.authKey, nonce)
    data = api_download(service, fileId, authorisation)

    print('Decrypting to temp file')
    tmpfile = decrypt_filedata(data, keys)

    return tmpfile, metadata['name']
예제 #4
0
def test_secretKeys_random_key_lengths():
    # test key generation without providing the master secretKey
    keys = secretKeys()
    assert len(keys.secretKey) == 16
    assert len(keys.encryptKey) == 16
    assert len(keys.encryptIV) == 12
    assert len(keys.authKey) == 64
    assert len(keys.metaKey) == 16
    assert len(keys.deriveNewAuthKey('drowssap', 'https://send.server/download/aFileID/#someSecretKey' )) == 64
예제 #5
0
def encrypt_file(file, keys=secretKeys()):
    '''Encrypt file data with the same method as the Send browser/js client'''
    key = keys.encryptKey
    iv = keys.encryptIV
    encData = tempfile.SpooledTemporaryFile(max_size=SPOOL_SIZE, mode='w+b')
    cipher = Cryptodome.Cipher.AES.new(key, Cryptodome.Cipher.AES.MODE_GCM, iv)

    pbar = progbar(fileSize(file))

    for chunk in iter(lambda: file.read(CHUNK_SIZE), b''):
        encData.write(cipher.encrypt(chunk))
        pbar.update(len(chunk))

    pbar.close()
    encData.write(cipher.digest())
    file.close()

    encData.seek(0)
    return encData