o
    "“iJ  ã                   @   s0  d dl mZmZmZ d dl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lZd dlmZ d dlmZmZ d dlmZ d dlmZmZ d d	l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% ddl&m'Z' G dd„ dƒZ(G dd„ dƒZ)G dd„ deƒZ*G dd„ de+ƒZ,dS )é    )ÚListÚOptionalÚDict)Ú	b64decode)ÚIntEnumN)Úx509)ÚhashesÚserialization)ÚECDSA)ÚSHA1ÚSHA256)ÚocspÚoid)Úcrypto)ÚAppTransaction)Ú_get_cattrs_converteré   )ÚEnvironment)ÚResponseBodyV2DecodedPayload)ÚJWSTransactionDecodedPayload)ÚJWSRenewalInfoDecodedPayloadc                   @   s¶   e Zd ZdZ	ddee dededede	e
 f
dd	„Zd
edefdd„Zdedefdd„Zdedefdd„Zde	e de	e
 de	e fdd„Zdedefdd„Zdedefdd„ZdS )ÚSignedDataVerifierz]
    A class providing utility methods for verifying and decoding App Store signed data.
    NÚroot_certificatesÚenable_online_checksÚenvironmentÚ	bundle_idÚapp_apple_idc                 C   sD   t |ƒ| _|| _|| _|| _|| _|tjkr|d u r tdƒ‚d S d S )Nz9appAppleId is required when the environment is Production)	Ú_ChainVerifierÚ_chain_verifierÚ_environmentÚ
_bundle_idÚ_app_apple_idÚ_enable_online_checksr   Ú
PRODUCTIONÚ
ValueError)Úselfr   r   r   r   r   © r&   új/var/www/html/premium_crap/venv/lib/python3.10/site-packages/appstoreserverlibrary/signed_data_verifier.pyÚ__init__   s   
ÿzSignedDataVerifier.__init__Úsigned_renewal_infoÚreturnc                 C   s0   t tƒ |  |¡t¡}|j| jkrttjƒ‚|S )aº  
        Verifies and decodes a signedRenewalInfo obtained from the App Store Server API, an App Store Server Notification, or from a device
        See https://developer.apple.com/documentation/appstoreserverapi/jwsrenewalinfo

        :param signed_renewal_info: The signedRenewalInfo field
        :return: The decoded renewal info after verification
        :throws VerificationException: Thrown if the data could not be verified
        )	r   r   Ú	structureÚ_decode_signed_objectr   r   ÚVerificationExceptionÚVerificationStatusÚINVALID_ENVIRONMENT)r%   r)   Údecoded_renewal_infor&   r&   r'   Úverify_and_decode_renewal_info/   s   

z1SignedDataVerifier.verify_and_decode_renewal_infoÚsigned_transactionc                 C   sF   t tƒ |  |¡t¡}|j| jkrttjƒ‚|j	| j
kr!ttjƒ‚|S )a½  
        Verifies and decodes a signedTransaction obtained from the App Store Server API, an App Store Server Notification, or from a device
        See https://developer.apple.com/documentation/appstoreserverapi/jwstransaction

        :param signed_transaction: The signedTransaction field
        :return: The decoded transaction info after verification
        :throws VerificationException: Thrown if the data could not be verified
        )r   r   r+   r,   ÚbundleIdr    r-   r.   ÚINVALID_APP_IDENTIFIERr   r   r/   )r%   r2   Údecoded_transaction_infor&   r&   r'   Ú$verify_and_decode_signed_transaction>   s   	

z7SignedDataVerifier.verify_and_decode_signed_transactionÚsigned_payloadc                 C   s²   |   |¡}ttƒ |t¡}d}d}d}|jr#|jj}|jj}|jj}n-|jr3|jj}|jj}|jj}n|j	rP|j	j}|j	j}|j	j
rM|j	j
 d¡rMtj}ntj}|  |||¡ |S )a€  
        Verifies and decodes an App Store Server Notification signedPayload
        See https://developer.apple.com/documentation/appstoreservernotifications/signedpayload

        :param signedPayload: The payload received by your server
        :return: The decoded payload after verification
        :throws VerificationException: Thrown if the data could not be verified
        NÚSANDBOX)r,   r   r   r+   Údatar3   Ú
appAppleIdr   ÚsummaryÚexternalPurchaseTokenÚexternalPurchaseIdÚ
startswithr   r8   r#   Ú_verify_notification)r%   r7   Údecoded_dictÚdecoded_signed_notificationr   r   r   r&   r&   r'   Úverify_and_decode_notificationN   s*   
	

z1SignedDataVerifier.verify_and_decode_notificationc                 C   sB   || j ks| jtjkr|| jkrttjƒ‚|| jkrttjƒ‚d S ©N)	r    r   r   r#   r!   r-   r.   r4   r/   )r%   r   r   r   r&   r&   r'   r?   n   s
    


ÿz'SignedDataVerifier._verify_notificationÚsigned_app_transactionc                 C   sf   |   |¡}ttƒ |t¡}|j}|j| jks"| jtj	kr'|j
| jkr'ttjƒ‚|| jkr1ttjƒ‚|S )a[  
        Verifies and decodes a signed AppTransaction
        See https://developer.apple.com/documentation/storekit/apptransaction

        :param signed_app_transaction: The signed AppTransaction
        :return: The decoded AppTransaction after validation
        :throws VerificationException: Thrown if the data could not be verified
        )r,   r   r   r+   ÚreceiptTyper3   r    r   r   r#   r:   r!   r-   r.   r4   r/   )r%   rD   r@   Údecoded_app_transactionr   r&   r&   r'   Ú!verify_and_decode_app_transactiont   s   
	$


z4SignedDataVerifier.verify_and_decode_app_transactionÚ
signed_objc           
   
   C   s,  zvt j|ddid�}| jtjks| jtjkr|W S t  |¡}| d¡}|d u s-t|ƒdkr1t	dƒ‚| d¡}|d u s>d|krBt	d	ƒ‚| d
¡d urN| d
¡n| d¡}| j
sZ|d u r^t ¡ nt|ƒd }| j || j
|¡}t j||dgd�W S  ty„ }	 z|	‚d }	~	w t	y• }	 zttjƒ|	‚d }	~	ww )NÚverify_signatureF)ÚoptionsÚx5cr   zx5c claim was emptyÚalgÚES256zAlgorithm was not ES256Ú
signedDateÚreceiptCreationDateiè  )Ú
algorithms)ÚjwtÚdecoder   r   ÚXCODEÚLOCAL_TESTINGÚget_unverified_headerÚgetÚlenÚ	Exceptionr"   ÚtimeÚintr   Úverify_chainr-   r.   ÚVERIFICATION_FAILURE)
r%   rH   Údecoded_jwtÚunverified_headersÚ
x5c_headerÚalgorithm_headerÚsigned_dateÚeffective_dateÚsigning_keyÚer&   r&   r'   r,   †   s,   


""€€ÿz(SignedDataVerifier._decode_signed_objectrC   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚbytesÚboolr   Ústrr   rZ   r(   r   r1   r   r6   r   rB   r?   r   rG   Údictr,   r&   r&   r&   r'   r      s(    	úþýüû
ú" r   c                   @   sÄ   e Zd ZdZdZddee fdd„Zdee de	d	e
d
efdd„Zdee de	d	e
d
efdd„Zdejdefdd„Zdejdejdejfdd„Zdee d
ee fdd„Zdee defdd„ZdS )r   é    i„  Tr   c                 C   s   || _ || _i | _d S rC   )Úenable_strict_checksr   Úverified_certificates_cache)r%   r   rn   r&   r&   r'   r(   ¡   s   
z_ChainVerifier.__init__ÚcertificatesÚperform_online_checksrb   r*   c                 C   sJ   |rt |ƒdkr|  |¡}|d ur|S | j|||d�}|r#|  ||¡ |S )Nr   )rp   rq   rb   )rW   Úget_cached_public_keyÚ_verify_chain_without_cachingÚput_verified_public_key)r%   rp   rq   rb   Úcached_public_keyÚverified_public_keyr&   r&   r'   r[   ¦   s   
z_ChainVerifier.verify_chainc              
   C   s²  t | jƒdkrttjƒ‚t |ƒdkrttjƒ‚t ¡ }z@| jD ]}t tj	|¡}| 
|¡ q| jr8| tjj¡ t tj	t|d dd�¡}t tj	t|d dd�¡}t |||g¡}	W n tym }
 zttjƒ|
‚d }
~
ww | tjj|tjjd�¡ z
|	 ¡  |	 ¡ }W n ty— }
 zttjƒ|
‚d }
~
ww |  |d  ¡ d¡ |  |d  ¡ d¡ |rÈ|  |d |d	 |d	 ¡ |  |d |d |d	 ¡ | ¡  ¡ jtj j!tj"j#d
� $¡ S )Nr   é   T)Úvalidater   )Útzz1.2.840.113635.100.6.11.1z1.2.840.113635.100.6.2.1é   ©ÚencodingÚformat)%rW   r   r-   r.   ÚINVALID_CERTIFICATEÚINVALID_CHAIN_LENGTHr   Ú	X509StoreÚload_certificateÚFILETYPE_ASN1Úadd_certrn   Ú	set_flagsÚX509StoreFlagsÚX509_STRICTr   ÚX509StoreContextrX   Úset_timeÚdatetimeÚfromtimestampÚtimezoneÚutcÚverify_certificateÚget_verified_chainr\   Ú	check_oidÚto_cryptographyÚcheck_ocsp_statusÚ
public_keyÚpublic_bytesr	   ÚEncodingÚPEMÚPublicFormatÚSubjectPublicKeyInforR   )r%   rp   rq   rb   Útrusted_storeÚtrusted_cert_bytesÚtrusted_certÚ	leaf_certÚintermediate_certÚverification_contextrd   Útrusted_chainr&   r&   r'   rs   °   sJ   


€ÿ€ÿþüz,_ChainVerifier._verify_chain_without_cachingÚcertr   c              
   C   s>   z|j  t |¡¡ W d S  ty } zttjƒ|‚d }~ww rC   )Ú
extensionsÚget_extension_for_oidr   ÚObjectIdentifierrX   r-   r.   r\   )r%   rŸ   r   rd   r&   r&   r'   r�   Ô   s   €ÿz_ChainVerifier.check_oidÚissuerÚrootc                 C   s®  t  ¡ }| | ¡ | ¡ tƒ ¡}| ¡ }| ¡ j tj	j
j¡j}dd„ |D ƒ}|D �]'}tj|jjddi| tjj¡d�}	|	jdk�rQt  |	j¡}
|
jt jjk�rQ|g}|
jD ]}| tj |¡¡ qWd }|D ]Q}|
jr©|  ¡  !¡ jtjjtj"j#d�}t$ %¡ }| &|¡ | '¡  | (¡  | (¡ \}}t) *t+ƒ ¡}| ,|¡ | -¡ |
jkr¨|} nqg|
j.r¸|
j.|j/ 0¡ kr¸|} nqg|d u rÂt1t2j3ƒ‚| ¡ jtjjd�| ¡ jtjjd�kr×n.t 4¡ }| 5|¡ | 5|¡ t 6||g ¡}| 7¡  t	j8j9| ¡ j :tj;¡jj<v�rt1t2j3ƒ‚| ¡  =¡  >|
j?|
j@tA|
jBƒ¡ |
jCD ]8}t  ¡ }| | ¡ | ¡ |jD¡}| ¡ }|jEt jFjGk�rO|jH|jHk�rO|jI|jIk�rO|jJ|jJk�rO  d S �qq)t1t2j3ƒ‚)	Nc                 S   s    g | ]}|j tjjjkr|‘qS r&   )Úaccess_methodr   r   ÚAuthorityInformationAccessOIDÚOCSP)Ú.0Úvalr&   r&   r'   Ú
<listcomp>ã   s     z4_ChainVerifier.check_ocsp_status.<locals>.<listcomp>zContent-Typezapplication/ocsp-request)Úheadersr9   éÈ   r{   )r|   )Kr   ÚOCSPRequestBuilderÚadd_certificater�   r   Úbuildr    r¡   r   r   ÚExtensionOIDÚAUTHORITY_INFORMATION_ACCESSÚvalueÚrequestsÚpostÚaccess_locationr“   r	   r”   ÚDERÚstatus_codeÚload_der_ocsp_responseÚcontentÚresponse_statusÚOCSPResponseStatusÚ
SUCCESSFULrp   Úappendr   ÚX509Úfrom_cryptographyÚresponder_key_hashÚ
get_pubkeyÚto_cryptography_keyr–   r—   Úasn1ÚDecoderÚstartÚenterÚreadr   ÚHashr   ÚupdateÚfinalizeÚresponder_nameÚsubjectÚrfc4514_stringr-   r.   r\   r€   rƒ   r‡   r�   ÚExtendedKeyUsageOIDÚOCSP_SIGNINGÚget_extension_for_classÚExtendedKeyUsageÚ_usagesr’   ÚverifyÚ	signatureÚtbs_response_bytesr
   Úsignature_hash_algorithmÚ	responsesÚhash_algorithmÚcertificate_statusÚOCSPCertStatusÚGOODÚserial_numberÚissuer_key_hashÚissuer_name_hash)r%   rŸ   r£   r¤   ÚbuilderÚreqÚauthority_valuesÚocspsÚoÚrÚ	ocsp_respÚcertsÚ	ocsp_certÚsigning_certÚpotential_signing_certÚsubject_public_key_infoÚdecoderÚ_r²   Údigestr˜   r�   Úsingle_responser&   r&   r'   r‘   Ú   s¢   ý
ý
üÿ

þ€
ÿþ


ý
ÿ
ÿ€
z _ChainVerifier.check_ocsp_statusc                 C   s8   | j  t|ƒ¡}|d u rd S |d t ¡ krd S |d S )Nr   r   )ro   rV   ÚtuplerY   )r%   rp   rv   r&   r&   r'   rr   9  s   z$_ChainVerifier.get_cached_public_keyrv   c                 C   sh   t   ¡ tj }||f| jt|ƒ< t| jƒtjkr0t| j ¡ ƒD ]\}}|d t   ¡ kr/| j|= qd S d S )Nr   )	rY   r   ÚCACHE_TIME_LIMITro   rï   rW   ÚMAXIMUM_CACHE_SIZEÚlistÚitems)r%   rp   rv   Úcache_expirationÚkÚvr&   r&   r'   rt   A  s   €ýz&_ChainVerifier.put_verified_public_keyN)T)re   rf   rg   rñ   rð   r   ri   r(   rk   rj   rZ   r[   rs   r   ÚCertificater�   r   r¾   r‘   r   rr   rt   r&   r&   r&   r'   r   �   s    
$_r   c                   @   s(   e Zd ZdZdZdZdZdZdZdZ	dS )	r.   r   r   rz   rw   é   é   é   N)
re   rf   rg   ÚOKr\   r4   r~   r   ÚINVALID_CHAINr/   r&   r&   r&   r'   r.   I  s    r.   c                       s"   e Zd Zdef‡ fdd„Z‡  ZS )r-   Ústatusc                    s   t ƒ  d|j ¡ || _d S )Nz Verification failed with status )Úsuperr(   Únamerý   )r%   rý   ©Ú	__class__r&   r'   r(   T  s   
zVerificationException.__init__)re   rf   rg   r.   r(   Ú__classcell__r&   r&   r   r'   r-   S  s    r-   )-Útypingr   r   r   Úbase64r   Úenumr   rY   r‰   rÃ   rQ   r³   Úcryptographyr   Úcryptography.hazmat.primitivesr   r	   Ú,cryptography.hazmat.primitives.asymmetric.ecr
   Ú%cryptography.hazmat.primitives.hashesr   r   Úcryptography.x509r   r   ÚOpenSSLr   Ú+appstoreserverlibrary.models.AppTransactionr   Ú+appstoreserverlibrary.models.LibraryUtilityr   Úmodels.Environmentr   Ú#models.ResponseBodyV2DecodedPayloadr   Ú#models.JWSTransactionDecodedPayloadr   Ú#models.JWSRenewalInfoDecodedPayloadr   r   r   r.   rX   r-   r&   r&   r&   r'   Ú<module>   s4     -
