
    6iP                         d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlm	Z	 d dl
Z
d dlZd dlZd dlZddZ	 ddZ	 ddZd Zd Zd	 Zd
 Zy)    N)Cipher
algorithmsmodes)default_backendc                    |d||d}t        j                  |d      }t        j                  |j	                  d            j                  d      j                  d      }t        j                  | j	                  d            j                  d      j                  d      }| d| }	|j	                  d      }
|dk(  rCt        j                  |
|	j	                  d      t        j                        j                         }n|d	k(  rCt        j                  |
|	j	                  d      t        j                        j                         }nV|d
k(  rCt        j                  |
|	j	                  d      t        j                        j                         }nt        d|       t        j                  |      j                  d      j                  d      }| d| d| }|S )a  
    Sign data using JWS with HMAC for BillDesk integration
    
    Args:
        payload_string (str): The data to sign (usually encrypted JWE)
        signing_key (str): BillDesk provided signing key
        key_id (str): BillDesk provided signing key ID
        client_id (str): BillDesk provided client ID
        algorithm (str): JWS algorithm (default: "HS256")
    
    Returns:
        str: JWS signed string
    JWT)algtypkidclientid,:
separatorsutf-8=.HS256HS384HS512Unsupported algorithm: )jsondumpsbase64urlsafe_b64encodeencodedecoderstriphmacnewhashlibsha256digestsha384sha512
ValueError)payload_stringsigning_keykey_id	client_id	algorithm
jws_headerheader_json
header_b64payload_b64signing_inputsigning_key_bytes	signaturesignature_b64jws_signed_datas                 7E:\Akash\Saasvaap\Navya-Bakers\orders\billdesk_utils.pysign_jws_billdeskr7   
   s   " 	J **ZJ?K))+*<*<W*EFMMgV]]^abJ **>+@+@+IJQQRYZaabefK "l!K=1M $**73GHH.0D0DW0Mw~~^eeg		g	HH.0D0DW0Mw~~^eeg		g	HH.0D0DW0Mw~~^eeg	29+>?? ,,Y7>>wGNNsSM $Ak]!M?CO    c                     dt        t        j                                | t        j                  d      ||	||
d|dddd}t        j                  |d	      }t        ||||      }t        ||||      }|||fS )
a  
    Complete BillDesk payment flow: Create payload -> Encrypt with JWE -> Sign with JWS
    
    Args:
        merc_id (str): Merchant ID
        amount (str): Payment amount
        return_url (str): Return URL
        encryption_key (str): Encryption key
        enc_key_id (str): Encryption key ID
        enc_client_id (str): Encryption client ID
        signing_key (str): Signing key
        sign_key_id (str): Signing key ID
        sign_client_id (str): Signing client ID
        currency (str): Currency code (default: "356" for INR)
        itemcode (str): Item code (default: "DIRECT")
        user_ip (str): User's IP address
    
    Returns:
        tuple: (original_payload, encrypted_data, signed_data)
    TEST%Y-%m-%dT%H:%M:%S+05:30internetIMozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0gapplication/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9init_channelip
user_agentaccept_headerorderidmercid
order_dateamountcurrencyruitemcodedevicer   r   )inttimestrftimer   r   encrypt_jwe_billdeskr7   )merc_idrH   
return_urlencryption_key
enc_key_idenc_client_idr)   sign_key_idsign_client_idrI   rK   user_ippayloadpayload_jsonencrypted_datasigned_datas                   r6   !encrypt_and_sign_billdesk_paymentr]   @   s    6 #diik*+,mm$=>&e G	
G  ::g*=L *,
TabN $NKn]K44r8   c	                     dt        t        j                                | t        j                  d      ||||d|dddd}	t        j                  |	d	      }
t        |
|||      S )
a\  
    Create and encrypt a BillDesk payment payload
    
    Args:
        merc_id (str): Merchant ID provided by BillDesk
        amount (str): Payment amount
        return_url (str): Return URL after payment
        encryption_key (str): BillDesk provided encryption key
        key_id (str): BillDesk provided encryption key ID
        client_id (str): BillDesk provided client ID
        currency (str): Currency code (default: "356" for INR)
        itemcode (str): Item code (default: "DIRECT")
        user_ip (str): User's IP address
    
    Returns:
        str: JWE encrypted payment data
    r:   r;   r<   r=   r>   r?   rD   r   r   )rM   rN   rO   r   r   rP   )rQ   rH   rR   rS   r*   r+   rI   rK   rX   rY   rZ   s              r6   encrypt_billdesk_paymentr_   v   sv    , #diik*+,mm$=>&e G	
G" ::g*=L  nfiPPr8   c           	      *   |j                  d      }t        |      dk  r|j                  dd      }nt        |      dkD  r|dd }dd||d}t        j                  |d	      }t        j                  |j                  d            j                  d      j                  d
      }t        j                  d      }t        t        j                  |      t        j                  |      t!                     }	|	j#                         }
|j                  d      }|
j%                  |       | j                  d      }|
j'                  |      |
j)                         z   }|
j*                  }d}t        j                  |      j                  d      j                  d
      }t        j                  |      j                  d      j                  d
      }t        j                  |      j                  d      j                  d
      }| d| d| d| d| 	}|S )aq  
    Encrypt data using JWE with AES-256-GCM for BillDesk integration
    
    Args:
        response_string (str): The payload to encrypt
        encryption_key (str): BillDesk provided encryption key
        key_id (str): BillDesk provided encryption key ID
        client_id (str): BillDesk provided client ID
    
    Returns:
        str: JWE encrypted string
    r           NdirA256GCM)r	   encr   r   r   r   r      backendascii r   )r   lenljustr   r   r   r   r   r   osurandomr   r   AESr   GCMr   	encryptorauthenticate_additional_dataupdatefinalizetag)response_stringrS   r*   r+   key
jwe_headerr.   r/   ivcipherrq   aadpayload_bytes
ciphertextauth_tagencrypted_keyiv_b64ciphertext_b64tag_b64jwe_encrypted_datas                       r6   rP   rP      s    


(C 3x"}iiE"	SB#2h 	J **ZJ?K))+*<*<W*EFMMgV]]^abJ 
BB JNN3'2@QRF  "I 

G
$C**3/ $**73M!!-093E3E3GGJ }}H M%%b)009@@EF--j9@@IPPQTUN&&x077@GGLG '<qq.AQQRSZR[\r8   c                    	 | j                  d      }t        |      dk(  rF|\  }}}|ddt        |      dz  z
  dz  z  z   }	 t        j                  |      j	                  d      }n)t        |      dk(  r| }nt        dt        |       d	      |j                  d      }	t        |	      dk7  rt        d
t        |	             |	\  }
}}}}|
ddt        |
      dz  z
  dz  z  z   }	 t        j                  |      j	                  d      }t        j                  |      }|j                  d      dk7  rt        d|j                  d       d      |j                  d      dk7  rt        d|j                  d       d      	 |j                  d      }|j                  d      rt        j                  |dd        }t        |      dk7  rt        dt        |             	 d }|rt        d      	  ||      } ||      } ||      }t        |      dk7  rt        dt        |       d      	 t        t        j                   |      t#        j$                  ||      t'                     }|j)                         }|
j                  d      }|j+                  |       |j-                  |      |j/                         z   }	 |j	                  d      }t        j                  |      }t3        |t4              st        d#|       |S # t
        $ r}t        dt        |             d }~ww xY w# t
        $ r}t        dt        |             d }~ww xY w# t
        $ r}t        dt        |             d }~ww xY w# t
        $ r}t        dt        |             d }~ww xY w# t
        $ r}t        d t        |             d }~ww xY w# t        j0                  $ r}t        d!t        |             d }~wt
        $ r}t        d"t        |             d }~ww xY w# t
        $ r}t        d t        |             d }~ww xY w)$Nr      r      r   zFailed to decode JWS payload:    zInvalid format - got z# parts, expected 3 (JWS) or 5 (JWE)z,Invalid JWE format - must have 5 parts, got z&Failed to decode or parse JWE header: r	   rc   r   z, expected 'dir're   rd   zUnsupported encryption method: z, expected 'A256GCM'zb64:ra   z%Encryption key must be 32 bytes, got zInvalid encryption key: c                 `    | ddt        |       dz  z
  dz  z  z   }t        j                  |      S )Nr   r   )rk   r   urlsafe_b64decode)datapaddeds     r6   base64url_decodez!decrypt.<locals>.base64url_decode#  s4    CAD	A$5#:;;F++F33r8   z0Expected empty encrypted key for 'dir' algorithmz!Failed to decode JWE components: rf   zInvalid IV length: z, expected 12rg   ri   Decryption failed: z Failed to parse decrypted JSON: z!Failed to decode decrypted data: z$Decrypted data is not a dictionary: )splitrk   r   r   r   	Exceptionr'   strr   loadsgetr   
startswith	b64decoder   r   ro   r   rp   r   	decryptorrr   rs   rt   JSONDecodeError
isinstancedict)r[   rS   partsjws_header_b64jws_payload_b64jws_signature_b64jws_payload_paddedr   e	jwe_partsr/   encrypted_key_b64r   r   r   header_b64_paddedr.   headerrw   r   ry   r}   r~   rz   r   r{   decrypted_bytesdecrypted_stringdecrypted_jsons                                r6   decryptr      sx   f9$$S) u:?AF>NO->!031s??SVW?W;W[\:\3]!]L%+%=%=>P%Q%X%XY`%a" Z1_!/4SZL@cdee ',,S1	y>QKCPYNK[\]]IRF
%v~w 'S_q5H1HA0M)NN	P 223DELLWUKZZ,F
 ::e%6vzz%7H6IIYZ[[::e	)>vzz%?P>QQefgg	B ''0C((0&&~ab'9:3x2~ #HS
!STT 	4 OPP	K!&)B).9J'0H r7b=23r7)=IJJ	=JNN3/2x1HRaRcdF((*I##G,C2237'..z:Y=O=O=QQO
	K.55g>!ZZ(89N .$/CNCSTUUu  L #A#a&!JKKL>  	PEc!fXNOO	P   	B7Ax@AA	B  	K@QIJJ	K  	=23q6(;<<	= ## 	J?AxHII 	K@QIJJ	K  9.s1vh7889s   ?P, $L &BP, )9L7 "A$P, AM &P, 8N &P, 7BN/ 	&O /P, 	L4L//L44P, 7	M MMP, 	N(M??NP, 	N,N''N,,P, /	O8OOP, P)*PP)P$$P))P, ,	Q5QQc                 p    	 t        | |      }|S # t        $ r}t        dt        |             d}~ww xY w)a  
    Decrypt JWE data using AES-256-GCM for BillDesk integration
    Handles both direct JWE and nested JWS->JWE formats
    
    Args:
        encrypted_data (str): The JWE encrypted string or JWS containing JWE
        encryption_key (str): BillDesk provided encryption key
    
    Returns:
        dict: Decrypted and parsed JSON payload with 'bdorderid' key
    
    Raises:
        ValueError: If decryption, JSON parsing, or structure validation fails
    r   N)r   r   r'   r   )r[   rS   r   r   s       r6   decrypt_jwe_billdeskr   O  s@    9 @ 9.s1vh7889s    	505c                 p   | j                  d      }t        dt        |              t        |      dk(  rt        d       |\  }}}	 |ddt        |      dz  z
  z  dz  z   }t        j                  t        j                  |      j                  d            }t        dt        j                  |d	
              	 |ddt        |      dz  z
  z  dz  z   }t        j                  |      j                  d      }t        d|        |j                  d      }	t        dt        |	              t        |	      dk(  r{	 |	d   ddt        |	d         dz  z
  z  dz  z   }
t        j                  t        j                  |
      j                  d            }t        dt        j                  |d	
              nt        |      dk(  rt        d       	 |d   ddt        |d         dz  z
  z  dz  z   }t        j                  t        j                  |      j                  d            }t        dt        j                  |d	
              t        d       y#  t        d       Y xY w#  t        d       Y xY w# t        $ r}t        d|        Y d}~Md}~ww xY w#  t        d       Y dxY w)z?
    Analyze the structure of encrypted data from BillDesk
    r   zNumber of parts: r   z Format: JWS (JSON Web Signature)r   r   r   zJWS Header:    )indentzCould not decode JWS headerzJWS Payload (JWE): zJWE parts in payload: r   r   zJWE Header: zCould not decode JWE headerzCould not decode JWS payload: Nz!Format: JWE (JSON Web Encryption)z2--------------------------------------------------)
r   printrk   r   r   r   r   r   r   r   )r[   r   r   r   r   jws_header_paddedr-   r   jws_payloadr   jwe_header_paddedrx   r   header_paddedr   s                  r6   analyze_encrypted_datar   e  s      %E	c%j\
*+
5zQ01=B:):	1 .C<ORS<S8S1TWX1X XF$<$<=N$O$V$VW^$_`JLJq!A BCD
	8!03!c/>RUV>V:V3WZ[3[![ 223EFMMgVK'}56 $))#.I*3y>*:;<9~"9(1!sa#iPQlBSVWBW>W7X[\7\(\%!%F,D,DEV,W,^,^_f,g!hJLJq)I(JKL 
Uq12	1!!Hsa#eAh-!2C.C'Dq'HHMZZ 8 8 G N Nw WXFLF1!= >?@ 
(OG	1/0$978 	821#677	8	1/0sF   
A4I ?BJ A:I0 A:J& I-0I?=J 	J#JJ#&J5)r   )356DIRECTz	123.0.0.1)r   r   r    r"   &cryptography.hazmat.primitives.ciphersr   r   r   cryptography.hazmat.backendsr   rm   rN   requestsuuidr7   r]   r_   rP   r   r   r    r8   r6   <module>r      s[        L L 8 	  3r P[25n GR)Q\>Bg9T9,3r8   