
    `gj                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZ ddlmZmZmZ  G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d d      ZddZ G d d      Zy)zWeCom BizMsgCrypt-compatible AES-CBC encryption for callback mode.

Implements the same wire format as Tencent's official ``WXBizMsgCrypt``
SDK so that WeCom can verify, encrypt, and decrypt callback payloads.
    )annotationsN)Optional)ElementTree)default_backend)Cipher
algorithmsmodesc                      e Zd Zy)WeComCryptoErrorN__name__
__module____qualname__     W/root/.hermes/venv/lib/python3.12/site-packages/plugins/platforms/wecom/wecom_crypto.pyr   r          r   r   c                      e Zd Zy)SignatureErrorNr   r   r   r   r   r      r   r   r   c                      e Zd Zy)DecryptErrorNr   r   r   r   r   r      r   r   r   c                      e Zd Zy)EncryptErrorNr   r   r   r   r   r   "   r   r   r   c                  4    e Zd ZdZedd       Zedd       Zy)PKCS7Encoder    c                    | j                   t        |      | j                   z  z
  }|dk(  r| j                   }t        |g      |z  }||z   S )Nr   )
block_sizelenbytes)clstextamount_to_padpads       r   encodezPKCS7Encoder.encode)   sI    #d)cnn*DEANNM]O$}4czr   c                    |st        d      |d   }|dk  s|| j                  kD  rt        d      || d  t        |g      |z  k7  rt        d      |d |  S )Nzempty decrypted payload   zinvalid PKCS7 paddingzmalformed PKCS7 padding)r   r   r    )r!   	decryptedr$   s      r   decodezPKCS7Encoder.decode1   so    899m7cCNN*677cTUucU|c118993$r   N)r"   r    returnr    )r)   r    r+   r    )r   r   r   r   classmethodr%   r*   r   r   r   r   r   &   s-    J     r   r   c                    t        | |||g      }t        j                  dj                  |      j	                  d            j                         S )N utf-8)sortedhashlibsha1joinr%   	hexdigest)token	timestampnonceencryptpartss        r   _sha1_signaturer:   =   s@    E9eW56E<<--g67AACCr   c                  N    e Zd ZdZd	dZd
dZddZdddZddZe	ddd       Z
y)WXBizMsgCryptzKMinimal WeCom callback crypto helper compatible with BizMsgCrypt semantics.c                   |st        d      |st        d      t        |      dk7  rt        d      |st        d      || _        || _        t	        j
                  |dz         | _        | j                  d d | _        y )Nztoken is requiredzencoding_aes_key is required+   z!encoding_aes_key must be 43 charszreceive_id is required=   )
ValueErrorr   r5   
receive_idbase64	b64decodekeyiv)selfr5   encoding_aes_keyrB   s       r   __init__zWXBizMsgCrypt.__init__E   s    011;<< B&@AA566
$##$4s$:;((3B-r   c                L    | j                  ||||      }|j                  d      S )Nr/   )decryptr*   )rG   msg_signaturer6   r7   echostrplains         r   
verify_urlzWXBizMsgCrypt.verify_urlT   s%    ]IugF||G$$r   c                   t        | j                  |||      }||k7  rt        d      	 t        j                  |      }	 t        t        j                  | j                        t        j                  | j                        t                     }|j                         }	|	j!                  |      |	j#                         z   }
t$        j'                  |
      }|dd  }t)        j*                  t-        j.                  d|d d       d         }|dd|z    }|d|z   d  j'                  d      }|| j2                  k7  rt        d
      |S # t
        $ r}t        d|       |d }~ww xY w# t0        $ r  t
        $ r}t        d	|       |d }~ww xY w)Nzsignature mismatchzinvalid base64 payload: backendr@   I   r   r/   zdecrypt failed: zreceive_id mismatch)r:   r5   r   rC   rD   	Exceptionr   r   r   AESrE   r	   CBCrF   r   	decryptorupdatefinalizer   r*   socketntohlstructunpackr   rB   )rG   rL   r6   r7   r8   expectedcipher_textexccipherrX   paddedrN   content
xml_lengthxml_contentrB   s                   r   rK   zWXBizMsgCrypt.decryptX   s   "4::y%I}$ !566	J **73K	BJNN4884eii6HRaRcdF((*I%%k2Y5G5G5IIF ''/EBCjGfmmC!&Ea&HIJ!!A
N3K Z188AJ (455%  	J!9#?@cI	J   	 	B!1#78cA	Bs0   E  C*E& 	E#EE#&F8FFNc                (   |xs | j                         }|xs+ t        t        t        d      j	                                     }| j                  |j                  d            }t        | j                  |||      }t        j                  d      }|t        j                  |d      _        |t        j                  |d      _        |t        j                  |d      _        |t        j                  |d      _        t        j                  |d	      S )
Ntimer/   xmlEncryptMsgSignature	TimeStampNonceunicode)encoding)_random_noncestrint
__import__rh   _encrypt_bytesr%   r:   r5   ETElement
SubElementr"   tostring)rG   	plaintextr7   r6   r8   	signatureroots          r   r8   zWXBizMsgCrypt.encryptr   s    -++-DSF);)@)@)B%C!D	%%i&6&6w&?@#DJJ	5'J	zz% .5dI&+3<dN+009dK(-,1dG$){{4)44r   c                   	 t        j                  d      }t        j                  dt	        j
                  t        |                  }||z   |z   | j                  j                  d      z   }t        j                  |      }t        t        j                  | j                        t        j                  | j                         t#                     }|j%                         }|j'                  |      |j)                         z   }t+        j,                  |      j/                  d      S # t0        $ r}	t3        d|	       |	d }	~	ww xY w)Nr@   rS   r/   rQ   zencrypt failed: )osurandomr]   packr[   htonlr   rB   r%   r   r   r   rV   rE   r	   rW   rF   r   	encryptorrY   rZ   rC   	b64encoder*   rU   r   )
rG   rawrandom_prefixmsg_lenpayloadrc   rb   r   	encryptedra   s
             r   rt   zWXBizMsgCrypt._encrypt_bytes~   s    
	BJJrNMkk#v||CH'=>G#g-3doo6L6LW6UUG!((1FJNN4884eii6HRaRcdF((*I!((093E3E3GGI##I.55g>> 	B!1#78cA	Bs   D%D( (	E1E  Ec                N    ddj                  fdt        |       D              S )N>0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZr.   c              3  H   K   | ]  }t        j                          y w)N)secretschoice).0_alphabets     r   	<genexpr>z.WXBizMsgCrypt._random_nonce.<locals>.<genexpr>   s     GAw~~h/Gs   ")r3   range)lengthr   s    @r   rp   zWXBizMsgCrypt._random_nonce   s!    SwwGvGGGr   )r5   rq   rH   rq   rB   rq   )
rL   rq   r6   rq   r7   rq   rM   rq   r+   rq   )
rL   rq   r6   rq   r7   rq   r8   rq   r+   r    )NN)ry   rq   r7   Optional[str]r6   r   r+   rq   )r   r    r+   rq   )
   )r   rr   r+   rq   )r   r   r   __doc__rI   rO   rK   r8   rt   staticmethodrp   r   r   r   r<   r<   B   s5    U %4
5B H Hr   r<   )
r5   rq   r6   rq   r7   rq   r8   rq   r+   rq   )r   
__future__r   rC   r1   r}   r   r[   r]   typingr   	xml.etreer   ru   cryptography.hazmat.backendsr   &cryptography.hazmat.primitives.ciphersr   r   r	   rU   r   r   r   r   r   r:   r<   r   r   r   <module>r      s    #   	     ' 8 L L	y 		% 		# 		# 	   .D
LH LHr   