3
b`<                 @   s   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 d dlmZmZ d dlmZmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlm Z  G dd dZ!dS )    N)DecodeError)text_format)get_random_bytes)random)
PKCS1_OAEPAES)CMACSHA256HMACSHA1)RSA)pss)Padding)wv_proto2_pb2)Session)Keyc               @   sN   e Zd Zdd ZdddZdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dS )Cdmc             C   s   t jt| _i | _d S )N)logging	getLogger__name__loggersessions)self r   :C:\Users\Broad\Desktop\BeinConnetFix\pywidevine\cdm\cdm.py__init__   s    zCdm.__init__NFc             C   s   | j jdj|| | j jd |jdkrbdjdd tdD }d}d	}|| | }|jd
}n(|jdkrztd}	|	}n| j j	d dS |rt
|ttfr|}
d| _n| j|}
d| _|
rt||
||}n| j j	d dS || j|< | j jd |S )Nz(open_session(init_data_b64={}, device={}zopening new cdm sessionZandroid c             s   s   | ]}t jd V  qdS )ZABCDEF0123456789N)r   choice).0_r   r   r   	<genexpr>    s    z#Cdm.open_session.<locals>.<genexpr>   Z01Z00000000000000asciiZchromezdevice type is unusable   TFzunable to parse init dataz0session opened and init data parsed successfully)r   debugformatinfoZsession_id_typejoinrangeencoder   error
isinstancebytes	bytearrayraw_pssh_parse_init_datar   r   )r   init_data_b64ZdeviceZraw_init_dataofflineZ
rand_asciiZcounterrest
session_idZ
rand_bytes	init_dataZnew_sessionr   r   r   open_session   s2    



zCdm.open_sessionc             C   s   t j }y(| jjd |jtj|dd   W n^ tk
r   | jjd y|jtj|dd  }W n  tk
r   | jjd d S X Y nX | jjd x"t	j
|j D ]}| jj| qW |S )Nz"trying to parse init_data directly    z:unable to parse as-is, trying with removed pssh box headerz-unable to parse, unsupported init data formatz
init_data:)	wv_proto2ZWidevineCencHeaderr   r$   ParseFromStringbase64	b64decoder   r*   r   MessageToString
splitlines)r   r0   Zparsed_init_dataZid_bytesliner   r   r   r/   =   s    zCdm._parse_init_datac             C   s^   | j jdj| | j jd || jkrD| jj| | j jd dS | j jdj| dS d S )Nzclose_session(session_id={})zclosing cdm sessionzcdm session closedr   zsession {} not foundr#   )r   r$   r%   r&   r   pop)r   r3   r   r   r   close_sessionN   s    
zCdm.close_sessionc             C   sV  | j jdj|| | j jd || jkr:| j jd dS | j| }tj }y|jt	j
| W n  tk
r   | j jd Y nX tj }|jr| j jd y|j|j W n  tk
r   | j jd dS X nD| j jd y|jt	j
| W n" tk
r   | j jd dS X | j jd	 x$tj|j D ]}| j j| q0W ||_d
|_dS )Nz/set_service_certificate(session_id={}, cert={})zsetting service certificatezsession id doesn't existr#   z%failed to parse cert as SignedMessagez&service cert provided as signedmessagez#failed to parse service certificatez0service cert provided as signeddevicecertificatezservice certificate:Tr   )r   r$   r%   r&   r   r*   r7   ZSignedMessager8   r9   r:   r   ZSignedDeviceCertificateTypeMsgr   r;   r<   service_certificateprivacy_mode)r   r3   Zcert_b64sessionmessagerB   r=   r   r   r   set_service_certificateY   s>    

zCdm.set_service_certificatec          "   C   s  | j jdj| | j jd || jkr8| j jd dS | j| }| jrRtj }ntj	 }tj
 }tjj|jjs| j jd dS t|jjd:}y|j|j }W n  tk
r   | j jd dS X W d Q R X | j jd | js
tj	jjd	|_|jjjjj|j ntjjjd	|_|j|jjj_|jr>tjjd
}ntjjd}||jjj_||jjj_tj j!jd|j_t"t#j# |j_$tj%jd|j_%|jj&rt'j(dd|j_)|j*r|jj+r<| j jd | j jd tj, }t|jj-d<}y|j|j }	W n" tk
r$   | j jd dS X W d Q R X |j.j| | j jd | j jd x$t/j0|j1 D ]}
| j j|
 qdW t2d}t2d}t3j4|t3j5|}|j6t7j8|j9 d}t:j;|j<j=j>}t?j4|}|j6|}tj@ }|j<j=jA|_A|j<j=jB|_C||_D||_E||_F|jjDj| n|jjGj| |jjHrLt:j;t|jjIj }||_Jn| j jd dS | j jd tKj4|jj9 }tLj4|jM|}||_N||_O| j jd x&t/j0|jOj1 D ]}
| j j|
 qW | j jd | j jdjtPjQ|j9  |j9 S )Nz"get_license_request(session_id={})zgetting license requestzsession ID does not existr#   z+no client ID blob available for this devicerbz%client id failed to parse as protobufzbuilding license requestZLICENSE_REQUESTZOFFLINEDEFAULTZNEWZCURRENT      z!vmp required, adding to client_idzreading vmp hashesz&vmp hashes failed to parse as protobufz?privacy mode & service certificate loaded, encrypting client idzunencrypted client id:r!   z4need device private key, other methods unimplementedzsigning license requestzlicense request:zlicense request createdzlicense request b64: {}l        )Rr   r$   r%   r&   r   r*   r.   r7   ZSignedLicenseRequestRawZSignedLicenseRequestZClientIdentificationospathexistsZdevice_configZdevice_client_id_blob_filenameopenr8   readr   ZMessageTypeZValuer@   rA   Z	ContentIdZCencIdZPsshZCopyFromr4   r1   ZLicenseTypeZ	RequestIdZLicenseRequestZRequestTypeinttimeZRequestTimeZProtocolVersionZsend_key_control_noncer   	randrangeZKeyControlNoncerC   ZvmpZ
FileHashesZdevice_vmp_blob_filenameZ_FileHashesr   r;   r<   r   r   newMODE_CBCZencryptr   padSerializeToStringr   Z	importKeyrB   Z_DeviceCertificateZ	PublicKeyr   ZEncryptedClientIdentificationZ	ServiceIdZSerialNumberZServiceCertificateSerialNumberZEncryptedClientIdZEncryptedClientIdIvZEncryptedPrivacyKeyZClientIdZprivate_key_availableZdevice_private_key_filename
device_keyr   r   sign	Signaturelicense_requestr9   	b64encode)r   r3   rD   rZ   Z	client_idfZ	cid_bytesZlicense_typeZ
vmp_hashesZ	vmp_bytesr=   Zcid_aes_keyZcid_ivZ
cid_cipherZencrypted_client_idZservice_public_keyZservice_cipherZencrypted_cid_keyZencrypted_client_id_protokeyhash	signaturer   r   r   get_license_request   s    







zCdm.get_license_requestc       $      C   s  | j jdj|| | j jd || jkr:| j jd dS | j| }|jsZ| j jd dS tj }y|j	t
j| W n  tk
r   | j jd dS X ||_| j jd x"tj|j D ]}| j j| qW | j jd tj|j}|j|j|_|jjj }d	| d
 }d| d }	d| }
d|	 }d|	 }d|	 }d|	 }tj|jtd}|j|
 |j }tj|jtd}|j| |j }tj|jtd}|j| |j }tj|jtd}|j| |j }tj|jtd}|j| |j }|| }|| }||jd< ||jd< ||jd< | j jd tj|jd td}|j|jj  | j jdj|j  t!j"|j# |j |j#kr| j jd t$dd}|j%t
j| W d Q R X t$dd}|j%|j  W d Q R X | j jd | j jdjt&|jj' x|jj'D ]}|j(r|j(}ntj)j*j+j,|j-j.d}|j'}|j/}tj)j*j+j,|j-}tj|jd tj0|d}|j|}|d krg } |j1}!x,|!j2 D ] \}"}#|#dkr| j3|"j4 qW t5|  ng } |j6j3t'||t7j8|d!|  qW | j jd" d#S )$Nz.provide_license(session_id={}, license_b64={})zdecrypting provided licensezsession does not existr#   z!generate a license request first!z)unable to parse license - check protobufszlicense:zderiving keys from session keys   ENCRYPTION s      s   AUTHENTICATION s                  )Z	ciphermodencZauth_1Zauth_2zverifying license signature)	digestmodz!calculated sig: {} actual sig: {}zElicense signature doesn't match - writing bin so they can be debuggedzoriginal_lic.binwbzparsed_lic.binzcontinuing anywayzkey count: {}zutf-8)ivZOPERATOR_SESSIONr!   zdecrypted all keysr   )9r   r$   r%   r&   r   r*   rZ   r7   ZSignedLicenser8   r9   r:   r   licenser   r;   r<   r   rS   rW   decryptZ
SessionKeyZsession_keyrA   rV   r   r   updatedigestZderived_keysr
   r	   	hexdigestbinasciihexlifyrY   rN   writelenr   ZIdZLicenseZKeyContainerZKeyTypeNamer@   r)   ZIvrT   Z_OperatorSessionKeyPermissionsZ
ListFieldsappendnameprintkeysr   Zunpad)$r   r3   license_b64rD   ri   r=   Zoaep_cipherZlic_req_msgZenc_key_baseZauth_key_baseZenc_keyZ
auth_key_1Z
auth_key_2Z
auth_key_3Z
auth_key_4Zcmac_objZenc_cmac_keyZauth_cmac_key_1Zauth_cmac_key_2Zauth_cmac_key_3Zauth_cmac_key_4Zauth_cmac_combined_1Zauth_cmac_combined_2Zlic_hmacr\   r]   Zkey_idZencrypted_keyrh   typecipherZdecrypted_keyZpermissionsZpermsZ
descriptorvaluer   r   r   provide_license   s    









 



$zCdm.provide_licensec             C   s*   || j kr| j | jS | jjd dS d S )Nzsession not foundr#   )r   rv   r   r*   )r   r3   r   r   r   get_keyse  s    
zCdm.get_keys)NF)r   
__module____qualname__r   r5   r/   r?   rF   r`   r{   r|   r   r   r   r   r      s   
"+pqr   )"r9   rK   rQ   rn   r   Zgoogle.protobuf.messager   Zgoogle.protobufr   ZCryptodome.Randomr   r   ZCryptodome.Cipherr   r   ZCryptodome.Hashr   r	   r
   r   ZCryptodome.PublicKeyr   ZCryptodome.Signaturer   ZCryptodome.Utilr   Zpywidevine.cdm.formatsr   r7   Zpywidevine.cdm.sessionr   Zpywidevine.cdm.keyr   r   r   r   r   r   <module>   s"   