o
    sh+L                     @  s  d dl mZ ddlmZmZmZmZmZ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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 m!Z!m"Z" d dl#Z#dZ$e%dZ&eG dd deZ'eG dd deZ(eG dd deZ)eG dd dZ*dZ+dZ,eG dd dZ-eG dd dZ.G d d! d!e/Z0eG d"d# d#eZ1eG d$d% d%eZ2eG d&d' d'Z3eG d(d) d)Z4eG d*d+ d+eZ5e!ej6ej7f Z8e!e.e3f Z9e!e0e4f Z:eG d,d- d-Z;d.d/ Z<G d0d1 d1eZ=dS )2    )annotations   )AttestationAttestationTypeAttestationResultInvalidDataInvalidSignaturecatch_builtins_validate_cert_common   )CoseKey)	bytes2int
ByteBuffer)IntEnumunique)default_backend)rsaec)hashes)x509)r   )	dataclass)TupleUnioncastN   z2.23.133.8.3c                   @  s   e Zd ZdZdZdZdZdS )TpmRsaScheme            N)__name__
__module____qualname__RSASSARSAPSSOAEPRSAES r'   r'   P/var/www/html/env_mimamsha/lib/python3.10/site-packages/fido2/attestation/tpm.pyr   <   s
    r   c                   @  s   e Zd ZdZdZdS )
TpmAlgAsymr   #   N)r    r!   r"   RSAECCr'   r'   r'   r(   r)   D   s    r)   c                   @  s&   e Zd ZdZdZdZdZd
ddZd	S )
TpmAlgHash            returnhashes.HashAlgorithmc                 C  sV   | t jkr	t S | t jkrt S | t jkrt S | t jkr$t S td| )Nz!_hash_alg is not implemented for )r-   SHA1r   SHA256SHA384SHA512NotImplementedErrorselfr'   r'   r(   	_hash_algQ   s   



zTpmAlgHash._hash_algN)r2   r3   )r    r!   r"   r4   r5   r6   r7   r;   r'   r'   r'   r(   r-   J   s    r-   c                   @  s   e Zd ZU ded< ded< dS )TpmsCertifyInfobytesnamequalified_nameN)r    r!   r"   __annotations__r'   r'   r'   r(   r<   ^   s   
 r<   s   TCGs   c                   @  sH   e Zd ZU dZded< ded< ded< ded< d	ed
< edddZdS )TpmAttestationFormatu  the signature data is defined by [TPMv2-Part2] Section 10.12.8 (TPMS_ATTEST)
    as:
      TPM_GENERATED_VALUE (0xff544347 aka "ÿTCG")
      TPMI_ST_ATTEST - always TPM_ST_ATTEST_CERTIFY (0x8017)
        because signing procedure defines it should call TPM_Certify
        [TPMv2-Part3] Section 18.2
      TPM2B_NAME
        size (uint16)
        name (size long)
      TPM2B_DATA
        size (uint16)
        name (size long)
      TPMS_CLOCK_INFO
        clock (uint64)
        resetCount (uint32)
        restartCount (uint32)
        safe (byte) 1 yes, 0 no
      firmwareVersion uint64
      attested TPMS_CERTIFY_INFO (because TPM_ST_ATTEST_CERTIFY)
        name TPM2B_NAME
        qualified_name TPM2B_NAME
    See:
      https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
      https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-3-Commands-01.38.pdf
    r=   r>   datazTuple[int, int, int, bool]
clock_infointfirmware_versionr<   attestedr2   c              
   C  s  t |}|d}|tkrtd|d}|tkrtdzL||d}||d}|d}|d}|d}|d}	|	d	vrPtd
|	dd|	dk}
|d}||d}||d}W n tjy{ } zt|d }~ww | ||||||
f|t||ddS )Nr.   z generated value field is invalidr   ztpmi_st_attest field is invalid!Hz!Q!LB)r   r   zinvalid value 0xxz for booleanr   )r>   r?   )r>   rB   rC   rE   rF   )	r   readTPM_GENERATED_VALUE
ValueErrorTPM_ST_ATTEST_CERTIFYunpackstructerrorr<   )clsrB   readergenerated_valuetpmi_st_attestr>   clockreset_countrestart_count
safe_valuesaferE   attested_nameattested_qualified_nameer'   r'   r(   parse   sB   







zTpmAttestationFormat.parseN)rB   r=   r2   rA   r    r!   r"   __doc__r@   classmethodr^   r'   r'   r'   r(   rA   h   s   
 rA   c                   @  s>   e Zd ZU dZded< ded< ded< ded< edd Zd	S )
TpmsRsaParmszParse TPMS_RSA_PARMS struct

    See:
    https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    section 12.2.3.5
    rD   	symmetricschemekey_bitsexponentc                 C  s  | d}|tjtjB @ }|tjtjB k}|s|tkrtd| d}|tjtjB @ }|tjk}|r@|ttjtj	fvr@td|tjtjB k}	|	rV|tjtj	fvrVtd|tjk}
|
rj|tj
tjtfvrjtd|ru|tfvrutd| d}| d}|dkrd	}| ||||S )
NrG    symmetric is expected to be NULLzlkey is an unrestricted signing key, scheme is expected to be TPM_ALG_RSAPSS, TPM_ALG_RSASSA, or TPM_ALG_NULLz[key is a restricted signing key, scheme is expected to be TPM_ALG_RSAPSS, or TPM_ALG_RSASSAzlkey is an unrestricted decryption key, scheme is expected to be TPM_ALG_RSAES, TPM_ALG_OAEP, or TPM_ALG_NULLzJkey is an restricted decryption key, scheme is expected to be TPM_ALG_NULLrH   r   i  )rO   
ATTRIBUTES
RESTRICTEDDECRYPTTPM_ALG_NULLrM   SIGN_ENCRYPTr   r#   r$   r%   r&   )rR   rS   
attributesrc   restricted_decryptionis_restricted_decryption_keyrd   restricted_signis_unrestricted_signing_keyis_restricted_signing_keyis_unrestricted_decryption_keyre   rf   r'   r'   r(   r^      s`   








zTpmsRsaParms.parseNr_   r'   r'   r'   r(   rb      s   
 rb   c                   @  s   e Zd ZedddZdS )Tpm2bPublicKeyRsarS   r   r2   c                 C  s   | | |dS NrG   rK   rO   )rR   rS   r'   r'   r(   r^     s   zTpm2bPublicKeyRsa.parseN)rS   r   r2   rt   )r    r!   r"   ra   r^   r'   r'   r'   r(   rt     s    rt   c                   @  s>   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdddZdS )TpmEccCurvezTPM_ECC_CURVE
    https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    section 6.4
    r   r   r      r.      r          r2   ec.EllipticCurvec                 C  sv   | t jkr	td| t jkrt S | t jkrt S | t jkr$t	 S | t j
kr-t S | t jkr6t S td| )NzNo such curvezcurve is not supported)rw   NONErM   	NIST_P192r   	SECP192R1	NIST_P224	SECP224R1	NIST_P256	SECP256R1	NIST_P384	SECP384R1	NIST_P521	SECP521R1r9   r'   r'   r(   to_curve&  s   






zTpmEccCurve.to_curveN)r2   r|   )r    r!   r"   r`   r}   r~   r   r   r   r   BN_P256BN_P638SM2_P256r   r'   r'   r'   r(   rw     s    rw   c                   @  s    e Zd ZdZeZdZdZdZdS )
TpmiAlgKdfzTPMI_ALG_KDF
    https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    section 9.28
    r{   !   "   N)	r    r!   r"   r`   rk   NULLKDF1_SP800_56AKDF2KDF1_SP800_108r'   r'   r'   r(   r   7  s    r   c                   @  s<   e Zd ZU ded< ded< ded< ded< edddZdS )TpmsEccParmsrD   rc   rd   rw   curve_idr   kdfrS   r   r2   c                 C  s^   | d}| d}|tkrtd|tkrtdt| d}t| d}| ||||S )NrG   rg   zscheme is expected to be NULL)rO   rk   rM   rw   r   )rR   rS   rc   rd   r   
kdf_schemer'   r'   r(   r^   K  s   

zTpmsEccParms.parseN)rS   r   r2   r   )r    r!   r"   r@   ra   r^   r'   r'   r'   r(   r   D  s   
 r   c                   @  s0   e Zd ZU dZded< ded< eddd	Zd
S )TpmsEccPointzTPMS_ECC_POINT
    https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    Section 11.2.5.2
    r=   rJ   yrS   r   r2   c                 C  s*   | |d}| |d}| ||S ru   rv   )rR   rS   rJ   r   r'   r'   r(   r^   d  s   
zTpmsEccPoint.parseN)rS   r   r2   r   r_   r'   r'   r'   r(   r   Z  s   
 r   c                   @  s@   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdS )rh   zObject attributes
    see section 8.3
      https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    r   r.   r   r{   @      i   i   i   i   i   l   	s N)r    r!   r"   r`   	FIXED_TPMST_CLEARFIXED_PARENTSENSITIVE_DATA_ORIGINUSER_WITH_AUTHADMIN_WITH_POLICYNO_DAENCRYPTED_DUPLICATIONri   rj   rl   SHALL_BE_ZEROr'   r'   r'   r(   rh   l  s    rh   c                   @  sl   e Zd ZU dZded< ded< ded< ded	< d
ed< ded< ded< edddZdddZdddZdS )TpmPublicFormata  the public area structure is defined by [TPMv2-Part2] Section 12.2.4
    (TPMT_PUBLIC)
    as:
      TPMI_ALG_PUBLIC - type
      TPMI_ALG_HASH - nameAlg
        or + to indicate TPM_ALG_NULL
      TPMA_OBJECT - objectAttributes
      TPM2B_DIGEST - authPolicy
      TPMU_PUBLIC_PARMS - type parameters
      TPMU_PUBLIC_ID - uniq
    See:
      https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
    r)   sign_algr-   name_algrD   rm   r=   auth_policy_Parameters
parameters_Uniquer   rB   r2   c           
      C  s   t |}t|d}t|d}|d}|tj@ dkr&td|d||d}|tjkr?t	
||}t
|}n|tjkrOt
|}t
|}n	td|dd| }	t|	dkrftd| |||||||S )	NrG   rH   r   z(attributes is not formated correctly: 0xrJ   z	sign alg z is not supportedz+there should not be any data left in buffer)r   r)   rO   r-   rh   r   rM   rK   r+   rb   r^   rt   r,   r   r   r8   len)
rR   rB   rS   r   r   rm   r   r   r   restr'   r'   r(   r^     s(   



zTpmPublicFormat.parse
_PublicKeyc                 C  s   | j tjkrtt| jj}ttt| j	}t
||t S | j tjkrCtt| j	}tt|jt|jtt| jj t S td| j )Nzpublic_key not implemented for )r   r)   r+   r   rb   r   rf   r   rt   r   r   RSAPublicNumbers
public_keyr   r,   r   r   EllipticCurvePublicNumbersrJ   r   r   r   r   r8   )r:   rf   modulusr   r'   r'   r(   r     s   zTpmPublicFormat.public_keyc                 C  s@   t d| j}tj| j t d}|| j ||	 7 }|S )u  
        Computing Entity Names

        see:
          https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf
        section 16 Names

        Name ≔ nameAlg || HnameAlg (handle→nvPublicArea)
          where
            nameAlg algorithm used to compute Name
            HnameAlg hash using the nameAlg parameter in the NV Index location
                     associated with handle
            nvPublicArea contents of the TPMS_NV_PUBLIC associated with handle
        rG   backend)
rP   packr   r   Hashr;   r   updaterB   finalize)r:   outputdigestr'   r'   r(   r>     s
   zTpmPublicFormat.nameN)rB   r=   r2   r   )r2   r   )r2   r=   )	r    r!   r"   r`   r@   ra   r^   r   r>   r'   r'   r'   r(   r     s   
 
r   c                 C  sn   t |  | jtj}|rtd| jtj}|std| jtj	}dd |j
D }d|vr5tdd S )Nz#Certificate should not have Subjectz.Certificate should have SubjectAlternativeNamec                 S  s   g | ]}|t kqS r'   )OID_AIK_CERTIFICATE).0rJ   r'   r'   r(   
<listcomp>  s    z&_validate_tpm_cert.<locals>.<listcomp>TzExtended key usage MUST contain the "joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)" OID.)r
   subjectget_attributes_for_oidr   NameOIDr   
extensionsget_extension_for_classSubjectAlternativeNameExtendedKeyUsagevalue)certsexthas_aikr'   r'   r(   _validate_tpm_cert  s   r   c                   @  s   e Zd ZdZedd ZdS )TpmAttestationtpmc              
   C  sH  d|v rt d|d }|d }|d }t|d t }t| t|| }z	t	
|d }	W n tyE }
 ztd|
d }
~
ww |jj|	 |jjkrWtd	zAt
|}|| }|j}tj|t d
}|| | }|j|kr~td|jj|	 krtd|||d  ttj|W S  ty   tdw )N
ecdaaKeyIdzECDAA not implementedalgx5ccertInfor   pubAreazunable to parse pubAreaz9attestation pubArea does not match attestedCredentialDatar   z5attestation does not sign for authData and ClientDataz;TPMS_CERTIFY_INFO does not include a valid name for pubAreasigz$signature of certInfo does not match)r8   r   load_der_x509_certificater   r   r   for_algfrom_cryptography_keyr   r   r^   	Exceptionr   credential_datar   rA   	_HASH_ALGr   r   r   r   rB   rF   r>   verifyr   r   ATT_CA_InvalidSignature)r:   	statement	auth_dataclient_data_hashr   r   	cert_infor   pub_keypub_arear]   r   att_to_be_signedhash_algr   rB   r'   r'   r(   r     sT   



zTpmAttestation.verifyN)r    r!   r"   FORMATr	   r   r'   r'   r'   r(   r     s    r   )>
__future__r   baser   r   r   r   r   r	   r
   coser   utilsr   r   enumr   r   cryptography.hazmat.backendsr   )cryptography.hazmat.primitives.asymmetricr   r   cryptography.hazmat.primitivesr   cryptographyr   cryptography.exceptionsr   dataclassesr   typingr   r   r   rP   rk   ObjectIdentifierr   r   r)   r-   r<   rL   rN   rA   rb   r=   rt   rw   r   r   r   rh   RSAPublicKeyEllipticCurvePublicKeyr   r   r   r   r   r   r'   r'   r'   r(   <module>   s^   $	
QT![