#!/usr/bin/python3
from univention.admin.password import krb5_asn1
import binascii
import heimdal

## Test data from Windows Server 2025 (decoded via s4search-decode):
#krb5Key:: MFShKzApoAMCARShIgQg7ITiJ+rgloeXxg8kzBu4IQF9HVk3iDdD/X8NwRE23hCiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=
 #      krb5_keytype: aes256-cts-hmac-sha384-192 (20)
#       keyblock:  b'7ITiJ+rgloeXxg8kzBu4IQF9HVk3iDdD/X8NwRE23hA='
#       saltstring:  UTOTEST242WIN.TESToikvefjw
#krb5Key:: MEShGzAZoAMCAROhEgQQvVrcCdVSvlTEVWY1X/tUlKIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==
 #      krb5_keytype: aes128-cts-hmac-sha256-128 (19)
#       keyblock:  b'vVrcCdVSvlTEVWY1X/tUlA=='
#       saltstring:  UTOTEST242WIN.TESToikvefjw
#krb5Key:: MFShKzApoAMCARKhIgQggc/4K0t4lsFJB5brLd1tsvF2A0Upc4/O6BJQj/R4ySaiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=
 #      krb5_keytype: aes256-cts-hmac-sha1-96 (18)
#       keyblock:  b'gc/4K0t4lsFJB5brLd1tsvF2A0Upc4/O6BJQj/R4ySY='
#       saltstring:  UTOTEST242WIN.TESToikvefjw

# Clear text password: Xyuhkefki345

## From OpenLDAP attributes:
# userPassword:: e0s1S0VZfQ==
# sambaNTPassword: 8CE133ED75F3320929C1DFEFCC2B7735
# krb5Key:: MFShKzApoAMCARShIgQg7ITiJ+rgloeXxg8kzBu4IQF9HVk3iDdD/X8NwRE23hCiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=
# krb5Key:: MEShGzAZoAMCAROhEgQQvVrcCdVSvlTEVWY1X/tUlKIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==
# krb5Key:: MFShKzApoAMCARKhIgQggc/4K0t4lsFJB5brLd1tsvF2A0Upc4/O6BJQj/R4ySaiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=
# krb5Key:: MEShGzAZoAMCARGhEgQQFg/L2ZBBSnwAo5hlLK/a5aIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==
# krb5Key:: MEShGzAZoAMCARehEgQQjOEz7XXzMgkpwd/vzCt3NaIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==
# pwhistory: {NT}$EF00EEB5E4C95DF2845934435A4ED7A0 {NT}$8CE133ED75F3320929C1DFEFCC2B7735
reference_attrs = [
    "MFShKzApoAMCARShIgQg7ITiJ+rgloeXxg8kzBu4IQF9HVk3iDdD/X8NwRE23hCiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=",
    "MEShGzAZoAMCAROhEgQQvVrcCdVSvlTEVWY1X/tUlKIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==",
    "MFShKzApoAMCARKhIgQggc/4K0t4lsFJB5brLd1tsvF2A0Upc4/O6BJQj/R4ySaiJTAjoAMCAQOhHAQaVVRPVEVTVDI0MldJTi5URVNUb2lrdmVmanc=",
    "MEShGzAZoAMCARGhEgQQFg/L2ZBBSnwAo5hlLK/a5aIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==",
    "MEShGzAZoAMCARehEgQQjOEz7XXzMgkpwd/vzCt3NaIlMCOgAwIBA6EcBBpVVE9URVNUMjQyV0lOLlRFU1RvaWt2ZWZqdw==",
]

def ms2025_hashes():
    hashes = {}
    for val in reference_attrs:
        key = binascii.a2b_base64(val)
        (keyblock, salt, _kvno) = heimdal.asn1_decode_key(key)
        enctype = keyblock.keytype()
        enctype_id = enctype.toint()
        hashes[enctype_id] = (keyblock, salt, _kvno)
    return hashes

def recalculate_hashes():
    upn = "oikvefjw@UTOTEST242WIN.TEST"
    pwd = "Xyuhkefki345"
    hash_list = krb5_asn1(upn, pwd)
    return hash_list

def compare_hashes(ms2025_values, calculated_values):
    for key in calculated_values:
        (keyblock, salt, _kvno) = heimdal.asn1_decode_key(key)
        enctype = keyblock.keytype()
        enctype_id = enctype.toint()
        print("krb5_keytype: %s (%d)" % (enctype, enctype_id))
        key_data = keyblock.keyvalue()
        print("keyblock         : ", binascii.b2a_base64(key_data).strip())
        ms_key_data = ms2025_values[enctype_id][0].keyvalue()
        print("keyblock (ms2025): ", binascii.b2a_base64(ms_key_data).strip())
        if enctype_id == 23:
            print("#\tas NThash:", binascii.b2a_hex(key_data).strip().upper())
        saltstring = salt.saltvalue()
        # print("saltstring: ", saltstring)
        print()

if __name__ == "__main__":
    ms2025_values = ms2025_hashes()
    calculated_values = recalculate_hashes()
    compare_hashes(ms2025_values, calculated_values)
