def gen_mac_login(): optestlib.p_debug('\n** Mac login details for accounts table') enc_login = {'email': Email, 'personalKey': SecretKey} muk = { 'k': optestlib.opb64e(sym_keys['mp']), 'key_ops': ['encrypt', 'decrypt'], 'alg': 'A256GCM', 'ext': True, 'key': 'oct', 'kid': 'mp' } srp = { 'hexX': optestlib.opb64e(sym_keys['srp-x']), 'params': { 'method': alg_srp, 'iterations': p2c_srp, 'alg': alg_muk, 'salt': optestlib.opb64e(p2s_srp) } } enc_login['masterUnlockKey'] = muk enc_login['SRPComputedXDictionary'] = srp optestlib.p_str("mac enc_login contents:", json.dumps(enc_login, indent=4)) return enc_login
def gen_rsa_key(ekid, pub=None, priv=None): if priv == None: new_priv = RSA.generate(2048) jwk_priv = RSAKey(key=new_priv).to_dict() iv = None else: iv = optestlib.opb64d(priv['iv']) jwk_priv = priv['key'] if pub == None: new_pub = new_priv.publickey() jwk_pub = RSAKey(key=new_pub).to_dict() else: jwk_pub = pub jwk_priv['alg'] = 'RSA-OAEP' jwk_priv['key_ops'] = ['decrypt'] jwk_priv['kid'] = ekid jwk_pub['key_ops'] = ['encrypt'] jwk_pub['alg'] = 'RSA-OAEP' jwk_pub['ext'] = True jwk_pub['kid'] = ekid optestlib.p_str("New Private key", json.dumps(jwk_priv, indent=4)) pri_keys[ekid] = jwk_priv pub_keys[ekid] = jwk_pub key_dat_str = json.dumps(jwk_priv) optestlib.p_debug('\n*** Encrypting pri key with AES kid %s' % ekid) iv, ct = optestlib.enc_aes_gcm(key_dat_str, sym_keys[ekid], iv=iv) optestlib.p_data('IV', iv, dump=False) optestlib.p_data('KEY', sym_keys[ekid], dump=False) optestlib.p_data('Ciphertext', ct, dump=False) priv_out = { 'kid': ekid, 'cty': 'b5+jwk+json', 'enc': 'A256GCM', 'data': optestlib.opb64e(ct), 'iv': optestlib.opb64e(iv) } optestlib.p_str("New Public key", json.dumps(jwk_pub, indent=4)) return jwk_pub, priv_out
def enc_win_login(): optestlib.p_debug('\n** Windows login details for accounts table') data = json.dumps({'accountKey': SecretKey, 'password': MasterPassword}) iv = read_default('win_enc_login_iv') padding = read_default('win_enc_login_padding') op_msg = optestlib.encrypt_opdata(data, sym_keys['win-mk'], sym_keys['win-mk-hmac'], iv=iv, padding=padding) return optestlib.opb64e(op_msg)
def gen_vault_key(name, ekid): global vault_access, vault_kids optestlib.p_debug('** Generating access keys for %s' % name) out = {"enc": "RSA-OAEP", "kid": ekid, "cty": "b5+jwk+json"} new_kid = read_default(name + '.uuid', decode=False) new_key = read_default(name + '.k') kid, sym_key = gen_sym_key(ekid, new_kid=new_kid, k=new_key) out['data'] = sym_key vault_access[name] = sym_key vault_kids[name] = kid return kid
def gen_emk(): global sym_keys optestlib.p_debug('\n** Generating Encrypted Master Key (EMK) block') win_mk = read_default('win_mk') or get_random_bytes(32) sym_keys['win-mk'] = win_mk win_mk_hmac = read_default('win_mk_hmac') or get_random_bytes(32) sym_keys['win-mk-hmac'] = win_mk_hmac optestlib.p_data('New MK', win_mk) optestlib.p_data('New MK HMAC Key', win_mk_hmac) emk_salt = read_default('emk_salt') or get_random_bytes(emk_slen) raw_derived_key = hashlib.pbkdf2_hmac('sha512', MasterPassword, emk_salt, emk_iter, 64) enc_key = raw_derived_key[0:32] enc_hmac_key = raw_derived_key[32:64] optestlib.p_data('MP-derived key', enc_key) optestlib.p_data('MP-derived HMAC key', enc_hmac_key) iv = read_default('win_emk_iv') padding = read_default('win_emk_padding') op_msg = optestlib.encrypt_opdata(win_mk + win_mk_hmac, enc_key, enc_hmac_key, iv=iv, padding=padding) emk = struct.pack('<I', emk_iter) # iterations emk += struct.pack('<I', emk_slen) # salt length emk += emk_salt emk += struct.pack('<I', len(op_msg)) emk += op_msg optestlib.p_data('Final EMK block', emk) return optestlib.opb64e(emk)
def gen_sym_key(ekid, new_kid=None, iv=None, k=None): out = {'kid': ekid, 'cty': 'b5+jwk+json'} if new_kid != None: kid = new_kid else: kid = gen_uuid() if k != None: new_key = k else: new_key = get_random_bytes(32) key_dat = { 'alg': 'A256GCM', 'ext': True, 'key_ops': ['decrypt', 'encrypt'], 'kty': 'oct', 'kid': kid } key_dat['k'] = optestlib.opb64e(new_key) key_dat_str = json.dumps(key_dat) optestlib.p_str("New symmetric key", json.dumps(key_dat, indent=4)) sym_keys[kid] = new_key if ekid == 'mp': # sym_keys['mk'] = new_key optestlib.p_debug('\n*** Encrypting sym key with AES kid %s' % ekid) iv, ct = optestlib.enc_aes_gcm(key_dat_str, sym_keys[ekid], iv=iv) optestlib.p_data('IV', iv, dump=False) optestlib.p_data('KEY', sym_keys[ekid], dump=False) optestlib.p_data('Ciphertext', ct, dump=False) out['iv'] = optestlib.opb64e(iv) out['data'] = optestlib.opb64e(ct) out['enc'] = 'A256GCM' else: # only the primary sym_key is itself AES encrypted, rest by RSA optestlib.p_debug('\n*** Encrypting sym key with RSA kid %s\n' % ekid) jwkj = '{"keys": [%s]}' % json.dumps(pub_keys[ekid]) jwk = load_jwks(jwkj)[0] optestlib.p_str('Public key e:', jwk.e) optestlib.p_str('Public key n:', jwk.n) RSA_Key = RSA.construct((jwk.n, jwk.e)) C = PKCS1_OAEP.new(RSA_Key) ct = C.encrypt(key_dat_str) out['enc'] = 'RSA-OAEP' out['data'] = optestlib.opb64e(ct) optestlib.p_debug('') optestlib.p_data('RSA-OAEP ciphertext', ct, dump=False) return kid, out
def gen_keyset(name, ekid): optestlib.p_debug('** Generating %s - encrypted by %s' % (name, ekid)) out = {'encrypted_by': ekid} iv = None try: if ekid == 'mp': iv = read_default(name + '.sym.iv') new_kid = read_default(name + '.uuid', decode=False) new_key = read_default(name + '.sym.k') kid, sym_key = gen_sym_key(ekid, new_kid=new_kid, iv=iv, k=new_key) new_pub = read_default(name + '.pub', decode=False) new_priv = read_default(name + '.priv', decode=False) rsa_pub, rsa_priv = gen_rsa_key(kid, pub=new_pub, priv=new_priv) except: kid, sym_key = gen_sym_key(ekid) rsa_pub, rsa_priv = gen_rsa_key(kid) if ekid == 'mp': sym_keys['mk'] = sym_keys[kid] sym_key['p2s'] = optestlib.opb64e(p2s_muk) sym_key['p2c'] = p2c_muk sym_key['alg'] = alg_muk out['uuid'] = kid out['enc_sym_key'] = sym_key out['enc_pri_key'] = rsa_priv out['pub_key'] = rsa_pub keysets[kid] = out return kid
def gen_local_vault_keys(): global sym_keys optestlib.p_debug( '\n** Generating MasterKey (MK) and OverviewKey (OK) (OnePassword local private vaults)' ) salt = read_default('local_vault.salt') or get_random_bytes(16) mkd = read_default('local_vault.mk.data') or get_random_bytes(256) mk_iv = read_default('local_vault.mk.iv') mk_padding = read_default('local_vault.mk.padding') okd = read_default('local_vault.ok.data') or get_random_bytes(64) ok_iv = read_default('local_vault.ok.iv') ok_padding = read_default('local_vault.ok.padding') data = optestlib.gen_local_vault_keys(MasterPassword, salt, mkd, mk_iv, mk_padding, okd, ok_iv, ok_padding) sym_keys['opv-mk'] = data['master_key'] sym_keys['opv-mk-hmac'] = data['master_key_hmac'] sym_keys['opv-ok'] = data['overview_key'] sym_keys['opv-ok-hmac'] = data['overview_key_hmac'] enc_master_key = data['enc_master_key_data'] enc_overview_key = data['enc_overview_key_data'] profile_data = { 'salt': optestlib.opb64e(salt), 'iterations': opk_iter, 'overview_key_data': optestlib.opb64e(enc_overview_key), 'master_key_data': optestlib.opb64e(enc_master_key) } return profile_data
def main(): global p2s_muk, p2s_srp optestlib.p_debug(" *** Generating Test Data ***") optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Deriving Master Unlock Key (MUK) (AES kid mp)') p2s_muk = read_default('muk_salt') or get_random_bytes(16) MUK = optestlib.compute_2skd(SecretKey, MasterPassword, Email, p2s_muk, p2c_muk, alg_muk) sym_keys['mp'] = MUK optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Deriving SRP-X') p2s_srp = read_default('srp_salt') or get_random_bytes(16) SRPx = optestlib.compute_2skd(SecretKey, MasterPassword, Email, p2s_srp, p2c_srp, alg_srp) sym_keys['srp-x'] = SRPx optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Generating keyset1') keyset1_kid = gen_keyset('keyset1', 'mp') optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Generating keyset2') keyset2_kid = gen_keyset('keyset2', keyset1_kid) optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Generating login detail records') mac_login_data = gen_mac_login() mac_login = enc_mac_login(keyset1_kid, mac_login_data) optestlib.p_debug('\n* Generating Windows EMK') emk = gen_emk() optestlib.p_debug('\n* Generating Windows login details') win_login = enc_win_login() optestlib.p_debug('\n* Generating private vault unlock keys') op_local_vault_keys = gen_local_vault_keys() op_local_vault_login = gen_local_login(mac_login_data) optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Generating vaults') vault1_kid = gen_vault_key('vault1', keyset1_kid) gen_vault_entry('vault1', vault1_kid) optestlib.p_debug( "\n\n**************************************************************") optestlib.p_debug('* Generating vault items') uuid = read_default('items.1.uuid') gen_item('items.1', 'vault1', uuid, title='My test!', url='https://example.com', user='******', password='******') optestlib.p_debug('** Local private vault item') old_vault_data = gen_old_vault_data() print "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" print " *** Generated Data ***\n" print("MUK data:") print(" Password: %s" % MasterPassword) print(" Secret Key: %s" % SecretKey) print(" Email: %s" % Email) print(" p2s: %s" % optestlib.opb64e(p2s_muk)) print(" p2c: %d" % p2c_muk) print(" alg: %s" % alg_muk) print(" MUK: %s" % optestlib.opb64e(MUK)) print("\nSRP data") print(" p2s: %s" % optestlib.opb64e(p2s_srp)) print(" p2c: %d" % p2c_srp) print(" alg: %s" % alg_srp) print(" SRP-X: %s" % optestlib.opb64e(SRPx)) print("\n\nMaster key (mk): %s" % optestlib.opb64e(sym_keys['mk'])) print("\n\nSymmetric Keys (kid, base64-encoded key):") for k in sorted(sym_keys): print(" %-26s %s" % (k, optestlib.opb64e(sym_keys[k]))) print("\n\nPublic Keys (kid, json dump of key):") for k in sorted(pub_keys): print(" %-26s %s\n" % (k, json.dumps(pub_keys[k], indent=4))) print("\n\nPrivate Keys (kid, json dump of key):") for k in sorted(pri_keys): print(" %-26s %s\n" % (k, json.dumps(pri_keys[k], indent=4))) print("\nKeyset 1:\n%s" % json.dumps(keysets[keyset1_kid], indent=4)) print("\nKeyset 2:\n%s" % json.dumps(keysets[keyset2_kid], indent=4)) print("\nmacOS enc_login:\n%s" % json.dumps(mac_login, indent=4)) print("\nEMK:\n%s" % emk) print("\nWindows enc_login:\n%s" % win_login) print("\nLocal vault key data:\n%s" % json.dumps(op_local_vault_keys, indent=4)) print("\nAccount enc_login encrypted for local vaults:\n%s" % json.dumps(op_local_vault_login, indent=4)) for vault in ['vault1']: print("\nVault Data for %s:\n" % vault) print(" * Vault access key\n%s" % (json.dumps(vault_access[vault]))) print(" * Vault attributes\n%s" % (json.dumps(vaults[vault]))) print("\nEncrypted vault items") for item in items: print json.dumps(items[item]), "\n" print("\nLocal private vault item") print json.dumps(old_vault_data)