Ejemplo n.º 1
0
 def test_core_types(self):
     self.archive(1)
     self.archive('two')
     self.archive(3.14)
     self.archive([1, 'two', 3.14])
     self.archive({'fruit': 'kiwi', 'veg': 'asparagus'})
     self.archive(b'hello')
     self.archive({'data': b'hello'})
     self.archive(timestamp(0))
     self.archive([timestamp(-4)])
Ejemplo n.º 2
0
 def test_circular_ref(self):
     obj = FooArchive('herp', timestamp(9001), 42,
                      ['strawberries', 'dragonfruit'], {'key': 'value'},
                      False, None)
     obj.recursive = obj
     plist = plistlib.loads(archiver.archive(obj))
     foo_obj = plist['$objects'][1]
     self.assertEqual(plistlib.UID(1), foo_obj['recurse'])
Ejemplo n.º 3
0
 def test_circular_ref(self):
     foo = FooArchive('herp', timestamp(9001), 42,
                      ['strawberries', 'dragonfruit'], {'key': 'value'},
                      False, None)
     foo.recursive = foo
     plist = bplist.parse(archiver.archive(foo))
     foo_obj = plist['$objects'][1]
     self.assertEqual(uid(1), foo_obj['recurse'])
 def from_andOtpJson(andOtpJson):
     label = andOtpJson.get("label")
     issuer = andOtpJson.get("issuer")
     secret = andOtpJson.get("secret")
     secret += "=" * ((8 - len(secret) % 8) % 8)
     secret = base64.b32decode(secret.encode())
     type = Type[andOtpJson.get("type")]
     algorithm = Algorithm[andOtpJson.get("algorithm")]
     digits = andOtpJson.get("digits")
     counter = 0   # andOtpJson.get("counter")  #not in andOtp json backup
     period = andOtpJson.get("period")
     refDate = None   # andOtpJson.get("refDate") #not in andOtp json backup
     hideInWidget = False # andOtpJson.get("hideInWidget")   #not in andOtp json backup
     ID = None #implement ID fkt in for-loop andOtpJson.get("ID") #not in andOtp json backup
     hideInMacWidget = True # andOtpJson.get("hideInMacWidget") #not in andOtp json backup
     lastModified = timestamp(time.time()) # andOtpJson.get("lastModified") #not in andOtp json backup
     icon = None # andOtpJson.get("icon") #not in andOtp json backup
     macWidgetIndex = -1 # andOtpJson.get("macWidgetIndex") #not in andOtp json backup
     widgetIndex = None #implement ID fkt in for-loop? #andOtpJson.get("widgetIndex") #not in andOtp json backup
     return OTPAccount(label, issuer, secret, type, algorithm, digits, counter, period, refDate, hideInWidget, ID, hideInMacWidget, lastModified, icon, macWidgetIndex, widgetIndex)
Ejemplo n.º 5
0
 def test_custom_type(self):
     foo = FooArchive('herp', timestamp(9001), 42,
                      ['strawberries', 'dragonfruit'], {'key': 'value'},
                      False, None)
def andotp_to_otpauth(encrypted_andotp_backup):
    ## Derive output file name from input basename
    file_basename = os.path.basename(encrypted_andotp_backup.name)
    filename_without_extension = file_basename.split('.')[0]
    output_filename = filename_without_extension + '.otpauthdb'
  
     ## Get password from user
    password = getpass.getpass(f'Password for export file {encrypted_andotp_backup.name}: ')

    ## Read binary data file     
    data = encrypted_andotp_backup.read()

    ## Get parts of the message containing decryption information
    iterations=data[:4]    
    iterations=int.from_bytes(iterations, "big") 
    salt=data[4:16] 
    iv=data[16:28]
    tag=data[-16:]
    data = data[28:-16]

    ## Key generation
    dk = hashlib.pbkdf2_hmac('sha1', password.encode('utf-8'), salt, iterations, dklen=32)

    ## Decryption
    cipher = AES.new(dk, AES.MODE_GCM, iv, mac_len=16)    
    try:
        plaintext = cipher.decrypt_and_verify(data,tag)
#        print("The message is authentic:", plaintext)
    except ValueError:
        print("Key incorrect or message corrupted")

    ## Create Json data    
    data= json.loads(plaintext.decode('utf-8'))
    ## Optional Show all account data on Screen (uncomment if desired)
#    print(json.dumps(data, indent = 4, sort_keys=True))

    ## Build OTPAccount Array for OTP Auth from andOTP Json File including ID creation
    ID =0
    accounts = []
    for transacc in data:
        transacc = OTPAccount.from_andOtpJson(transacc)
        ID += 1
        transacc.ID = str(ID)
        transacc.widgetIndex = ID-1
        accounts.append(transacc)

    ## Create Archive Dict and Folder List for plist OTP Auth Backup File
    newarchive = {}
    newarchive['Folders'] = [OTPFolder('Accounts',accounts,'1',timestamp(time.time()))]
    newarchive['DeletedAccountIDs'] = []
    newarchive['DeletedFolderIDs'] = []    
 
    ## Achive the inner dict as .plist data
    newarchive = DangerousArchive(newarchive).to_bytes()
  
    ## crypt #1 with user pw from andOTP File
    data = RawRNCryptor().encrypt(newarchive, password)
 
    ## Build and Repack outer Archive to .plist data
    repack = {
        "Version" : 1.1,
        "WrappedData" : data,
    }
    
    repack = DangerousArchive(repack).to_bytes()
 
    ## crypt 2 outer with OTP Auth specific details
    iv = bytes(16)
    key = hashlib.sha256('Authenticator'.encode('utf-8')).digest()
    fill=16-len(repack)%16
    repack += bytes([fill])*fill
    data = AES.new(key, AES.MODE_CBC, iv).encrypt(repack)
    
    ## Write output file. Same filename as input. Different extension
    f = open(output_filename, "wb")
    f.write(bytearray(data))
    f.close
    
    click.echo(f'Conversion finished. Encrypted with same password from andOTP Backup. Output file name: {output_filename}')