
    i~N                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J
r
  SSKJr  SSKJr  SSKJr  SSKJrJrJrJr   SSKJr  \R2                  " S	5      r " S
 S5      rS\S\4S jr S4S\S\ S\ S\ S\ S\S\RB                  \ \ \ 4   4S jjr"S\ S\ S\ S\S\S\RB                  \ \ \ 4   4S jr#S\ S\ 4S jr$S\ S\ S\ 4S jr%S\ S\ S\ 4S jr&S\ S \ S\ 4S! jr'S\S"\ S#\ S$\ S\ S\ 4S% jr(S\S\ 4S& jr)S\ S\ 4S' jr*S\S\ 4S( jr+S)\S\ S*\RX                  \   S\ 4S+ jr-S,\S\ S\ 4S- jr.S\ S\ S\ 4S. jr/S\ S\4S/ jr0S\S0\ S1\S\ 4S2 jr1S\S0\ S1\S\ 4S3 jr2g! \ a
    SSKJr   GN%f = f)5af  NTLM Cryptographic Operations

Implements the various cryptographic operations that are defined in `MS-NLMP Crypto Operations`_. Some crypto
operations aren't implemented due to it being a simple operation in Python.

.. _MS-NLMP Crypto Operations
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/26c42637-9549-46ae-be2e-90f6f1360193
    N)default_backend)Cipher)DES)md4)FileTimeNegotiateFlagsNTClientChallengeV2
TargetInfo)
algorithmsz!^[a-fA-F0-9]{32}:[a-fA-F0-9]{32}$c                   F    \ rS rSrSrS\SS4S jrS\S\4S jrSS	 jrS
r	g)	RC4Handle0   z1RC4 class to wrap the underlying crypto function.keyreturnNc                     Xl         [        R                  " U R                   5      n[        US [	        5       S9nUR                  5       U l        g )Nmodebackend)_keyr   ARC4r   r   	encryptor_handle)selfr   arc4ciphers       Q/home/james-whalen/.local/lib/python3.13/site-packages/spnego/_ntlm_raw/crypto.py__init__RC4Handle.__init__3   s:    	tyy)41BC'')    b_datac                 8    U R                   R                  U5      $ )z?Update the RC4 stream and return the encrypted/decrypted bytes.)r   update)r   r    s     r   r"   RC4Handle.update:   s    ||""6**r   c                     [         R                  " U R                  5      n[        US[	        5       S9nUR                  5       U l        g)z5Reset's the cipher stream back to the original state.Nr   )r   r   r   r   r   r   r   )r   r   r   s      r   resetRC4Handle.reset>   s5    tyy)41BC'')r   )r   r   )r   N)
__name__
__module____qualname____firstlineno____doc__bytesr   r"   r%   __static_attributes__ r   r   r   r   0   s0    ;*E *d *+U +u +*r   r   passwordr   c                 >    [        [        R                  U 5      5      $ )N)bool_NTLM_HASH_PATTERNmatchr/   s    r   is_ntlm_hashr5   E   s    "((233r   flagsnt_hashlm_hashserver_challengeclient_challengeno_lm_responsec           	          U [         R                  -  (       a   [        U[        X4SS -   5      5      nUS-   nO[        X5      =pgU(       d  [        X#5      n[	        U5      n[        XX'U5      n	XgU	4$ )a  Compute NT and LM Response for NTLMv1.

Computes the NT and LM Response for NTLMv1 messages. The response is dependent on the flags that were negotiated
between the client and server.

The pseudo-code for this function as documented under `NTLM v1 Authentication`_ is::

    Define ComputeResponse(NegFlg, ResponseKeyNT, ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge,
        ClientChallenge, Time, ServerName) As

        If (User is set to "" AND Passwd is set to "")
            -- Special case for anonymous authentication
            Set NtChallengeResponseLen to 0
            Set NtChallengeResponseMaxLen to 0
            Set NtChallengeResponseBufferOffset to 0

            Set LmChallengeResponse to Z(1)
        ElseIf
            If (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag is set in NegFlg)
                Set NtChallengeResponse to DESL(ResponseKeyNT,
                    MD5(ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge, ClientChallenge))[0..7])

                Set LmChallengeResponse to ConcatenationOf{ClientChallenge, Z(16)}
            Else
                Set NtChallengeResponse to DESL(ResponseKeyNT, CHALLENGE_MESSAGE.ServerChallenge)

                If (NoLMResponseNTLMv1 is TRUE)
                    Set LmChallengeResponse to NtChallengeResponse
                Else
                    Set LmChallengeResponse to DESL(ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge)
                EndIf
            EndIf
        EndIf

    Set SessionBaseKey to MD4(NTOWF)

Args:
    flags: The negotiated flags between the initiator and acceptor.
    nt_hash: The response key computed by :meth:`ntowfv1`.
    lm_hash: The response key computed by :meth:`lmowfv1`.
    server_challenge: The 8 byte nonce generated by the acceptor.
    client_challenge: The 8 byte nonce generated by the initiator.
    no_lm_response: Whether to compute (True) the `LmChallengeResponse` or not (False) when extended session
        security was not negotiated.

Returns:
    Tuple[bytes, bytes, bytes]: Returns the NTChallengeResponse, LMChallengeResponse and KeyExchangeKey.

.. _NTLM v1 Authentication:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5
N   s                   )r   extended_session_securitydeslmd5r   kxkey)
r6   r7   r8   r9   r:   r;   nt_responselm_responsesession_base_keykey_exchange_keys
             r   compute_response_v1rF   I   s{    v ~7777C(8BQ;O(O$PQ&,7 %)$CCw9K7|UgL\]%555r   timeav_pairsc                     [        X2US9nUR                  5       S-   n[        XU-   5      nXv-   n[        XU-   5      U-   n	[        X5      n
XU
4$ )a  Compute NT and LM Response for NTLMv2.

Computes the NT and LM Response for NTLMv2 messages. The response is dependent on the flags that were negotiated
between the client and server.

The pseudo-code for this function as documented under `NTLM v2 Authentication`_ is::

    Define ComputeResponse(NegFlg, ResponseKeyNT, ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge,
        ClientChallenge, Time, ServerName) As

        If (User is set to "" && Passwd is set to "")
            -- Special case for anonymous authentication
            Set NtChallengeResponseLen to 0
            Set NtChallengeResponseMaxLen to 0
            Set NtChallengeResponseBufferOffset to 0

            Set LmChallengeResponse to Z(1)
        Else
            Set temp to ConcatenationOf(Responserversion, HiResponserversion, Z(6), Time, ClientChallenge, Z(4),
                ServerName, Z(4))

            Set NTProofStr to HMAC_MD5(ResponseKeyNT, ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge,temp))

            Set NtChallengeResponse to ConcatenationOf(NTProofStr, temp)

            Set LmChallengeResponse to ConcatenationOf(
                HMAC_MD5(ResponseKeyLM, ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge, ClientChallenge)),
                ClientChallenge)
        EndIf

    Set SessionBaseKey to HMAC_MD5(ResponseKeyNT, NTProofStr)

Args:
    nt_hash: The response key computed by :meth:`ntwofv2`. The `ResponseKeyLM` is the same value so we only
        pass in the 1 key.
    server_challenge: The 8 byte nonce generated by the acceptor.
    client_challenge: The 8 byte nonce generated by the initiator.
    time: The FileTime to place in the NT hash.
    av_pairs: The TargetInfo AvPairs fields that are placed in the Authenticate message.

Returns:
    Tuple[bytes, bytes, bytes]: Returns the NTChallengeResponse, LMChallengeResponse and KeyExchangeKey.

.. _NTLM v2 Authentication:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3
)
time_stampr:   rH   s       )r	   packhmac_md5)r7   r9   r:   rG   rH   tempb_tempnt_proof_strrB   rC   rD   s              r   compute_response_v2rP      sg    j $\deDYY[..FG%>?L'K77G$GHK[[K6%555r   mc                 ^    [         R                  " S[        R                  " U 5      S-  5      $ )z5Simple wrapper function to generate a CRC32 checksum.z<Il    )structrK   binasciicrc32rQ   s    r   rU   rU      s#     ;;tX^^A.;<<r   kdc                 ^    [        [         R                  " U 5      5      R                  U5      $ )ap  DES encryption.

Indicates the encryption of an 8-byte data item `d` with the 7-byte key `k` using the Data Encryption Standard
(DES) algorithm in Electronic Codebook (ECB) mode. The result is 8 bytes in length ([FIPS46-2]).

Args:
    k: The 7-byte key to use in the DES cipher.
    d: The 8-byte data block to encrypt.

Returns:
    bytes: The encrypted data block.
)r   key56_to_key64encryptrW   rX   s     r   desr]      s%     s!!!$%--a00r   c                 T   U SS R                  SS5      n USS R                  SS5      n[        R                  " 5       nUR                  [	        U SS U5      5        UR                  [	        U SS U5      5        UR                  [	        U SS U5      5        UR                  5       $ )a   Encryption using the DES Long algorithm.

Indicates the encryption of an 8-byte data item `d` with the 16-byte key `k` using the Data Encryption
Standard Long (DESL) algorithm. The result is 24 bytes in length.

`DESL(K, D)` as by MS-NLMP `DESL`_ is computed as follows::

    ConcatenationOf(
        DES(K[0..6], D),
        DES(K[7..13], D),
        DES(ConcatenationOf(K[14..15], Z(5)), D),
    );

Args:
    k: The key to use for the DES cipher, will be truncated to 16 bytes and then padded to 21 bytes.
    d: The value to run through the DESL algorithm, will be truncated to 8 bytes.

Returns:
    bytes: The output of the DESL algorithm.

.. _DESL:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/26c42637-9549-46ae-be2e-90f6f1360193
N          r=         )ljustioBytesIOwriter]   getvalue)rW   rX   b_values      r   r?   r?      s    0 	
#2R!A	"1AwAjjlGMM#aeQ- MM#a"gq/"MM#afa.!r   r   datac                 d    [         R                  " X[        R                  S9R	                  5       $ )z.Simple wrapper function for a HMAC MD5 digest.)	digestmod)hmacnewhashlibr@   digest)r   rj   s     r   rL   rL     s     88C5<<>>r   rD   lmowfrC   c                    U [         R                  -  (       a  [        XUSS -   5      $ U [         R                  -  (       a'  USS n[	        USS U5      [	        USS S-   U5      -   $ U [         R
                  -  (       a  USS S-   $ U$ )a  NTLM KXKEY function.

The MS-NLMP `KXKEY`_ function used to derive the key exchange key for a security context. This is only for NTLMv1
contexts as NTLMv2 just re-uses the session base key.

Args:
    flags: The negotiate flags in the Challenge msg.
    session_base_key: The session base key from :meth:`compute_response_v1`.
    lmowf: The LM hash from :meth:`lmowfv1`.
    lm_response: The lm response from :meth:`compute_response_v1`.
    server_challenge: The server challenge in the Challenge msg.

Returns:
    bytes: The derived key exchange key.

.. _KXKEY:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/d86303b5-b29e-4fb9-b119-77579c761370
Nr=   rb   s   s           )r   r>   rL   lm_keyr]   non_nt_session_key)r6   rD   rq   rC   r9   r    s         r   rA   rA     s    2 ~777([!_*LMM	&&	&Ra5!9f%E!AJ9T,TV\(]]]	22	2Ray;&&  r   c                    [        U 5      (       a6  [        R                  " U R                  S5      S   R	                  5       5      $ U R	                  5       R                  SSS9R                  SS5      SS n[        R                  " 5       nS	 H"  u  p4UR                  [        XU S
5      5        M$     UR                  5       $ )aQ  NTLMv1 LMOWFv1 function

The Lan Manager v1 one way function as documented under `NTLM v1 Authentication`_.

The pseudo-code for this function is::

    Define LMOWFv1(Passwd, User, UserDom) as
        ConcatenationOf(
            DES(UpperCase(Passwd)[0..6], "KGS!@#$%"),
            DES(UpperCase(Passwd)[7..13], "KGS!@#$%"),
        );

Args:
    password: The password for the user.

Returns:
    bytes: The LMv1 one way hash of the user's password.

.. _NTLM v1 Authentication:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5
:r   zutf-8surrogatepasserrorsrc   ra   N))r   rb   )rb   rc   s   KGS!@#$%)r5   base64	b16decodesplitupperencoderd   re   rf   rg   r]   rh   )r/   
b_passwordb_hashstartends        r   lmowfv1r   :  s    , Hs 3A 6 < < >??
 !(((IOOPRT[\]`^`aJZZ\F'
S#.<= ( ??r   c                 J    [         R                  " U 5      R                  5       $ )z*Simple wrapper to generate a MD5 checksum.)ro   r@   rp   rV   s    r   r@   r@   _  s    ;;q>  ""r   c                     [        U 5      (       a6  [        R                  " U R                  S5      S   R	                  5       5      $ [        U R                  SSS95      $ )a  NTLMv1 NTOWFv1 function

The NT v1 one way function as documented under `NTLM v1 Authentication`_.

The pseudo-code for this function is::

    Define NTOWFv1(Passwd, User, UserDom) as MD4(UNICODE(Passwd))

Args:
    password: The password for the user.

Returns:
    bytes: The NTv1 one way hash of the user's password.

.. _NTLM v1 Authentication:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5
rv      	utf-16-lerw   rx   )r5   rz   r{   r|   r}   r   r~   r4   s    r   ntowfv1r   d  sO    $ Hs 3A 6 < < >??x{?CDDr   usernamedomain_namec                 n    U R                  5       U=(       d    S-   R                  S5      n[        X5      $ )an  NTLMv2 NTOWFv2 function

The NT v2 one way function as documented under `NTLM v2 Authentication`_.

The pseudo-code for this function is::

    Define NTOWFv2(Passwd, User, UserDom) as

        HMAC_MD5(MD4(UNICODE(Passwd)), UNICODE(ConcatenationOf(Uppercase(User), UserDom)))

Args:
    username: The username.
    nt_hash: The NT hash from :meth:`ntowfv1`.
    domain_name: The optional domain name of the user.

Returns:
    bytes: The NTv2 one way has of the user's credentials.

.. _NTLM v2 Authentication:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3
 r   )r}   r~   rL   )r   r7   r   b_users       r   ntowfv2r   |  s0    , nn+"34<<[IFG$$r   hc                 $    U R                  U5      $ )zKRC4 encryption of the data specified using the handle generated by rc4init.)r"   )r   rX   s     r   rc4r     s    88A;r   c                 6    [        U 5      R                  U5      $ )aq  RC4 encryption with an explicit key.

Indicates the encryption of data item `d` with the key `k` using the `RC4`_ algorithm.

Args:
    k: The key to use for the RC4 cipher.
    d: The data to encrypt.

Returns:
    bytes: The RC4 encrypted bytes.

.. _RC4K:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/26c42637-9549-46ae-be2e-90f6f1360193
)rc4initr"   r\   s     r   rc4kr     s     1:Qr   c                     [        U 5      $ )z9Initialization of the RC4 handle using the key specified.)r   )rW   s    r   r   r     s    Q<r   session_keyusagec                    U [         R                  -  (       aY  U [         R                  -  (       a  UnO#U [         R                  -  (       a  USS nOUSS nUS:X  a  SOSn[	        USU-  -   5      $ U [         R
                  -  (       d  U [         R                  -  (       a(  U [         R                  -  (       a  USS S-   $ USS S	-   $ U$ )
a  NTLM SEALKEY function.

The MS-NLMP `SEALKEY`_ function used to generate the sealing keys for a security context.

The pseudo-code for this function as documented under `SEALKEY`_ is::

    Define SEALKEY(NegFlg, ExportedSessionKey, Mode) as

        If (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag is set in NegFlg)

            If ( NTLMSSP_NEGOTIATE_128 is set in NegFlg)
                Set SealKey to ExportedSessionKey

            ElseIf ( NTLMSSP_NEGOTIATE_56 flag is set in NegFlg)
                Set SealKey to ExportedSessionKey[0..6]

            Else
                Set SealKey to ExportedSessionKey[0..4]

            Endif

            If (Mode equals "Client")
                Set SealKey to MD5(ConcatenationOf(SealKey,
                    "session key to client-to-server sealing key magic constant"))

            Else
                Set SealKey to MD5(ConcatenationOf(SealKey,
                    "session key to server-to-client sealing key magic constant"))

            Endif
        ElseIf ((NTLMSSP_NEGOTIATE_LM_KEY is set in NegFlg) or ((NTLMSSP_NEGOTIATE_DATAGRAM is set in NegFlg) and
                                                                (NTLMRevisionCurrent >= NTLMSSP_REVISION_W2K3)))

            If (NTLMSSP_NEGOTIATE_56 flag is set in NegFlg)
                Set SealKey to ConcatenationOf(ExportedSessionKey[0..6], 0xA0)

            Else
                Set SealKey to ConcatenationOf(ExportedSessionKey[0..4], 0xE5, 0x38, 0xB0)

            EndIf

        Else
            Set SealKey to ExportedSessionKey
        Endif
    EndDefine

Args:
    flags: The negotiated flags between the initiator and acceptor.
    session_key: The derived session key.
    usage: Whether the sealing key is for the 'initiate' or 'accept' context.

Returns:
    bytes: The derived sealing key.

.. _SEALKEY:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/bf39181d-e95d-40d7-a740-ab4ec3dc363d
Nrb      initiate   client-to-server   server-to-clients-   session key to %s sealing key magic constant    s   8)r   r>   key_128key_56r@   rs   datagram)r6   r   r   seal_key	directions        r   sealkeyr     s    t ~777>)))"H^***"2AH #2AH+0J+>'DW	8QT]]]^^	&&	&%.2I2I*I>(((r?W,, r?_44 r   c                 h    U [         R                  -  S:X  a  gUS:X  a  SOSn[        USU-  -   5      $ )aw  NTLM SIGNKEY function.

The MS-NLMP `SIGNKEY`_ function used to generate the signing keys for a security context.

The pseudo-code for this function as documented under `SIGNKEY`_ is::

    Define SIGNKEY(NegFlg, ExportedSessionKey, Mode) as

        If (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag is set in NegFlg)
            If (Mode equals "Client")
                Set SignKey to MD5(ConcatenationOf(ExportedSessionKey,
                    "session key to client-to-server signing key magic constant"))

            Else
                Set SignKey to MD5(ConcatenationOf(ExportedSessionKey,
                    "session key to server-to-client signing key magic constant"))

            Endif
        Else
            Set  SignKey to NIL

        Endif
    EndDefine

Args:
    flags: The negotiated flags between the initiator and acceptor.
    session_key: The derived session key.
    usage: Whether the signing key is for the 'initiate' or 'accept' context.

Returns:
    bytes: The derived singing key.

.. _SIGNKEY:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/524cdccb-563e-4793-92b0-7bc321fce096
r   r   r   r   r   s-   session key to %s signing key magic constant )r   r>   r@   )r6   r   r   r   s       r   signkeyr     sB    H ~7771<',
':#@SI{PS\\\]]r   )T)3r+   rz   rT   ro   rm   re   rerS   typingcryptography.hazmat.backendsr   &cryptography.hazmat.primitives.ciphersr   spnego._ntlm_raw.desr   spnego._ntlm_raw.md4r   spnego._ntlm_raw.messagesr   r   r	   r
   $cryptography.hazmat.decrepit.ciphersr   ImportErrorcompiler2   r   strr1   r5   intr,   TuplerF   rP   rU   r]   r?   rL   rA   r   r@   r   Optionalr   r   r   r   r   r   r.   r   r   <module>r      s       	 	   8 9 $ $ ? ZZ DE * **43 44 4  H6H6H6 H6 	H6
 H6 H6 \\%%&H6V=6=6=6 =6 	=6
 =6 \\%%&=6@=U =u =15 1U 1u 1 !E !e ! !H?% ?u ? ?
$ $ $  $  	$ 
 $  $ N"c "e "J#5 #U #
Ec Ee E0%c %E %8L %QV %49  5 
 E  e    $u  
P3 PU P3 P5 Pf)^3 )^U )^3 )^5 )^A   s   E$ $E43E4