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 rt1t2j3| jtjjd| jtjjdkrn.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     -
