def handle_ClientHello(sess, pdx, rx): if sess is None: sess = hexlify(get_random_bytes(17)).decode() + '-' + e64bs( get_random_bytes(56) + b'\0').rstrip() # This is our "server nonce" which the client will parrot back to us, along with its (encrypted) "client nonce" R_S = get_random_bytes(16) return pdx.decode( ), '''<?xml version="1.0" encoding="UTF-8"?><ServerHello xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SessionID="{sess}" Status="Continue" Version="1.0"><KeyType xmlns="">http://www.rsasecurity.com/rsalabs/otps/schemas/2005/09/otps-wst#SecurID-AES</KeyType> <EncryptionAlgorithm xmlns="">http://www.w3.org/2001/04/xmlenc#rsa-1_5</EncryptionAlgorithm> <EncryptionKey xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ds:KeyValue xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ds:RSAKeyValue xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ds:Modulus>{mod}</ds:Modulus> <ds:Exponent>{exp}</ds:Exponent> </ds:RSAKeyValue> </ds:KeyValue> </EncryptionKey> <Payload xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Nonce xmlns="">{R_S}</Nonce> </Payload> <Extensions xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Extension xmlns:ct-kip="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Data>{R_S}</Data> </Extension> </Extensions> <MacAlgorithm xmlns="">http://www.rsasecurity.com/rsalabs/otps/schemas/2005/11/ct-kip#ct-kip-prf-aes</MacAlgorithm> </ServerHello>'''.format(sess=sess, R_S=e64bs(R_S).rstrip(), mod=e64bs(number.long_to_bytes(pubk.n)).rstrip(), exp=e64bs(number.long_to_bytes(pubk.e)).rstrip())
def handle_ClientNonce(sess, pdx, rx): # Interesting data that the client has sent? Our nonce (parroted back) and their nonce (encrypted with our RSA key) # What we send back? Session ID, MAC, and a bunch of standard token config info (ID, expiration date, number of digits, etc.) # The client parrots our nonce back to us (a server with REEL SECURITEH would check that it matches, I guess...?) R_S = d64b(rx.find('Extensions/Extension/Data', ns).text) # Decrypt the ClientNonce (this will be the token secret) R_C_enc = d64b(rx.find('EncryptedNonce', ns).text) print("ENcrypted ClientNonce: {}".format(hexlify(R_C_enc))) R_C = cipher.decrypt(R_C_enc) print("DEcrypted ClientNonce: {}".format(hexlify(R_C))) tid = '%012d' % random.randint( 1, 999999999999) # Random 12-digit decimal number userid = 'u%05d' % random.randint(1, 9999) # Random 5-digit decimal number exp = datetime.now(timezone.utc) + timedelta(days=365) exp = exp.replace(hour=0, minute=0, second=0, microsecond=0).isoformat() # ISO8601 datetime K_TOKEN = ct_kip_prf_aes(R_C, number.long_to_bytes(pubk.n), b"Key generation", R_S) MAC = ct_kip_prf_aes(K_TOKEN, b"MAC 2 Computation", R_C) print("\n\nNegotiated token:") print(" K_TOKEN (hex): ", hexlify(K_TOKEN)) print(" MAC (hex): ", hexlify(MAC)) print(" Token ID: ", tid) print(" Token expiration date: ", exp) print("\n\n") return PROVISIONING_DATA, SERVER_FINISHED, dict(userid=userid, tid=e64s(tid).rstrip(), exp=exp, sess=sess, MAC=e64bs(MAC).rstrip())
def handle_ClientHello(sess, pdx, rx): # Interesting data that the client has sent? None whatsoever. # What we send back? Session ID, our nonce (plaintext), our RSA key. if sess is None: sess = hexlify(get_random_bytes(17)).decode() + '-' + e64bs( get_random_bytes(56) + b'\0').rstrip() # This is our "server nonce" which the client will parrot back to us, along with its (encrypted) "client nonce" R_S = get_random_bytes(16) return pdx.decode(), SERVER_HELLO, dict( sess=sess, R_S=e64bs(R_S).rstrip(), mod=e64bs(number.long_to_bytes(pubk.n)).rstrip(), exp=e64bs(number.long_to_bytes(pubk.e)).rstrip())
def handle_ClientNonce(sess, pdx, rx): # The client parrots our nonce back to us (a server with REEL SECURITEH would check that it matches, I guess...?) R_S = d64b(rx.find('Extensions/Extension/Data', ns).text) # Decrypt the ClientNonce (this will be the token secret) R_C_enc = d64b(rx.find('EncryptedNonce', ns).text) print("ENcrypted ClientNonce: {}".format(hexlify(R_C_enc))) R_C = cipher.decrypt(R_C_enc) print("DEcrypted ClientNonce: {}".format(hexlify(R_C))) tid = '%012d' % random.randint( 1, 999999999999) # Random 12-digit decimal number exp = datetime.utcnow() + timedelta(days=365) exp = exp.replace(hour=0, minute=0, second=0, microsecond=0).isoformat() + '+00:00' # ISO9601 datetime K_TOKEN = ct_kip_prf_aes(R_C, number.long_to_bytes(pubk.n), b"Key generation", R_S) MAC = ct_kip_prf_aes(K_TOKEN, b"MAC 2 Computation", R_C) print("K_TOKEN (hex): ", hexlify(K_TOKEN)) print("MAC (hex): ", hexlify(MAC)) print("Token ID: ", tid) print("Token expiration date: ", exp) pdr = '''<?xml version="1.0"?>\n<ProvisioningData>\n<PinType>0</PinType><AddPIN>1</AddPIN></ProvisioningData>\n''' r = '''<?xml version="1.0" encoding="UTF-8"?><ServerFinished xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SessionID="{sess}" Status="Success"><TokenID xmlns="">{tid}</TokenID> <KeyID xmlns="">{tid}</KeyID> <KeyExpiryDate xmlns="">{exp}</KeyExpiryDate> <ServiceID xmlns="">RSA CT-KIP</ServiceID> <UserID xmlns=""/> <Extensions xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Extension Critical="true" xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><OTPFormat>Decimal</OTPFormat> <OTPLength>8</OTPLength> <OTPMode xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Time TimeInterval="60" xmlns="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/> </OTPMode> </Extension> </Extensions> <Mac xmlns="" MacAlgorithm="http://www.rsasecurity.com/rsalabs/otps/schemas/2005/12/ct-kip#ct-kip-prf-aes" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">{MAC}</Mac> </ServerFinished>'''.format(tid=e64s(tid).rstrip(), exp=exp, sess=sess, MAC=e64bs(MAC).rstrip()) return pdr, r