o
    shE                     @  s  U 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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 d dlmZ d dlmZmZ d dlmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z% d dl&Z&d dl'Z'e'(e)Z*edddG dd deZ+edddG dd deZ,edddG dd deZ-edddG dd deZ.edddG dd deZ/edddG dd deZ0edddG dd  d eZ1edddG d!d" d"eZ2edddG d#d$ d$eZ3edddG d%d& d&eZ4eG d'd( d(e5eZ6edddG d)d* d*eZ7edddG d+d, d,eZ8edddG d-d. d.eZ9edddG d/d0 d0eZ:edddG d1d2 d2eZ;e%e:ge<f Z=e%e:e!e> ge<f Z?dFd6d7Z@dGd:d;ZAed<ZBd=eCd<< G d>d? d?e	ZDdHdDdEZEdS )I    )annotations   )AttestationObjectAaguid)AttestationUntrustedAttestationverify_x509_chainAttestationVerifier)websafe_decode_JsonDataObject)CoseKey)x509)default_backend)	dataclassfield)Enumunique)date)	b64decode	b64encode)
ContextVar)SequenceMappingAnyOptionalCallableNFT)eqfrozenc                   @  s   e Zd ZU ded< ded< dS )VersionintmajorminorN__name__
__module____qualname____annotations__ r'   r'   E/var/www/html/env_mimamsha/lib/python3.10/site-packages/fido2/mds3.pyr   7      
 r   c                   @  s   e Zd ZU ded< ded< dS )RogueListEntrybytesskr   r   Nr"   r'   r'   r'   r(   r*   =   r)   r*   c                   @  sF   e Zd ZU ded< ded< ded< ded< ded< ded< ded	< d
S )BiometricStatusReportr   
cert_levelstrmodalityeffective_datecertification_descriptorcertificate_numbercertification_policy_version"certification_requirements_versionNr"   r'   r'   r'   r(   r-   C   s   
 r-   c                   @  s6   e Zd ZU ded< ded< dZded< dZded< dS )CodeAccuracyDescriptorr   base
min_lengthNOptional[int]max_retriesblock_slowdownr#   r$   r%   r&   r:   r;   r'   r'   r'   r(   r6   N   s
   
 r6   c                   @  sf   e Zd ZU ededddZded< ededddZded< dZd	ed
< dZ	d	ed< dZ
d	ed< dS )BiometricAccuracyDescriptorNselfAttestedFRRname)defaultmetadatazOptional[float]self_attested_frrselfAttestedFARself_attested_farr9   max_templatesr:   r;   )r#   r$   r%   r   dictrC   r&   rE   rF   r:   r;   r'   r'   r'   r(   r=   V   s   
 

r=   c                   @  s.   e Zd ZU ded< dZded< dZded< dS )PatternAccuracyDescriptorr   min_complexityNr9   r:   r;   r<   r'   r'   r'   r(   rH   c   s   
 rH   c                   @  s>   e Zd ZU dZded< dZded< dZded< dZded	< dS )
VerificationMethodDescriptorNOptional[str]user_verification_methodz Optional[CodeAccuracyDescriptor]ca_descz%Optional[BiometricAccuracyDescriptor]ba_descz#Optional[PatternAccuracyDescriptor]pa_desc)r#   r$   r%   rL   r&   rM   rN   rO   r'   r'   r'   r(   rJ   j   s
   
 rJ   c                   @  s&   e Zd ZU ded< ded< ded< dS )RgbPaletteEntryr   rgbNr"   r'   r'   r'   r(   rP   r   s   
 rP   c                   @  sR   e Zd ZU ded< ded< ded< ded< ded< ded< ded< d	Zd
ed< d	S )#DisplayPngCharacteristicsDescriptorr   widthheight	bit_depth
color_typecompressionfilter	interlaceNz#Optional[Sequence[RgbPaletteEntry]]plte)r#   r$   r%   r&   r\   r'   r'   r'   r(   rT   y   s   
 rT   c                   @  sn   e Zd ZU eedddZded< eedddZded< ded< ded	< ded
< eedddZded< dS )EcdaaTrustAnchorXr?   rB   r/   xYycsxsyG1Curveg1_curveN)	r#   r$   r%   r   rG   r`   r&   rb   rg   r'   r'   r'   r(   r]      s   
 r]   c                   @  sL   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ZdZdZdS )AuthenticatorStatuszStatus of an Authenitcator.NOT_FIDO_CERTIFIEDFIDO_CERTIFIEDUSER_VERIFICATION_BYPASSATTESTATION_KEY_COMPROMISEUSER_KEY_REMOTE_COMPROMISEUSER_KEY_PHYSICAL_COMPROMISEUPDATE_AVAILABLEREVOKEDSELF_ASSERTION_SUBMITTEDFIDO_CERTIFIED_L1FIDO_CERTIFIED_L1plusFIDO_CERTIFIED_L2FIDO_CERTIFIED_L2plusFIDO_CERTIFIED_L3FIDO_CERTIFIED_L3plusN)r#   r$   r%   __doc__ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   r'   r'   r'   r(   rh      s"    rh   c                   @  s   e Zd ZU ded< eeejdd dddZded	< dZ	d
ed< eee
dd dddZded< dZded< dZded< dZded< dZded< dZded< dS )StatusReportrh   statusc                 C     |   S N	isoformatr`   r'   r'   r(   <lambda>       zStatusReport.<lambda>deserialize	serializeNrB   rA   zOptional[date]r1   r9   authenticator_versionc                 C  s   t |  S r|   r   decoder   r'   r'   r(   r      s    Optional[bytes]certificaterK   urlr2   r3   r4   r5   )r#   r$   r%   r&   r   rG   r   fromisoformatr1   r   r   r   r   r2   r3   r4   r5   r'   r'   r'   r(   ry      s&   
 ry   c                   @  sF   e Zd ZU eedddZded< ded< dZded	< dZd
ed< dS )ExtensionDescriptorfail_if_unknownr?   r_   boolr/   idNr9   tagrK   data)	r#   r$   r%   r   rG   r   r&   r   r   r'   r'   r'   r(   r      s
   
 r   c                   @  s  e Zd ZU ded< ded< ded< ded< ded	< eed
d ddZded< ded< ded< ded< ded< eedd dd ddZded< dZded< dZ	ded< eee
jdd dddZded < eed!d d"d dddZd#ed$< dZd%ed&< dZded'< dZd(ed)< dZd(ed*< dZd+ed,< dZd+ed-< dZd.ed/< dZded0< dZded1< eed2d3ddZd4ed5< dZd6ed7< dZded8< dZd9ed:< dZd;ed<< dS )=MetadataStatementr/   descriptionr   r   schemazSequence[Version]upvzSequence[str]attestation_typesc                 C     dd | D S )Nc                 S  s   g | ]	}d d |D qS )c                 S     g | ]}t |qS r'   )rG   .0r`   r'   r'   r(   
<listcomp>       z9MetadataStatement.<lambda>.<locals>.<listcomp>.<listcomp>r'   )r   xsr'   r'   r(   r          .MetadataStatement.<lambda>.<locals>.<listcomp>r'   )xssr'   r'   r(   r          zMetadataStatement.<lambda>)r   r_   z0Sequence[Sequence[VerificationMethodDescriptor]]user_verification_detailskey_protectionmatcher_protectionattachment_hint
tc_displayc                 C  r   )Nc                 S  r   r'   r   r   r'   r'   r(   r      r   r   r'   r   r'   r'   r(   r      r   c                 C  r   )Nc                 S  s   g | ]}t | qS r'   r   r   r'   r'   r(   r          r   r'   r   r'   r'   r(   r      r   r   Sequence[bytes]attestation_root_certificatesNrK   legal_headeraaidc                 C     t | S r|   r/   r   r'   r'   r(   r      r   r   Optional[Aaguid]aaguidc                 C  r   )Nc                 S     g | ]}t |qS r'   r+   fromhexr   r'   r'   r(   r          r   r'   r   r'   r'   r(   r      r   c                 C  r   )Nc                 S     g | ]}|  qS r'   hexr   r'   r'   r(   r      r   r   r'   r   r'   r'   r(   r      r   Optional[Sequence[bytes]]'attestation_certificate_key_identifierszOptional[Mapping[str, str]]alternative_descriptionsprotocol_familyzOptional[Sequence[str]]authentication_algorithmspublic_key_alg_and_encodingszOptional[bool]is_key_restricted#is_fresh_user_verification_requiredr9   crypto_strengthoperating_envtc_display_content_typetcDisplayPNGCharacteristicsr?   z7Optional[Sequence[DisplayPngCharacteristicsDescriptor]]tc_display_png_characteristicsz$Optional[Sequence[EcdaaTrustAnchor]]ecdaa_trust_anchorsiconz'Optional[Sequence[ExtensionDescriptor]]supported_extensionszOptional[Mapping[str, Any]]authenticator_get_info)r#   r$   r%   r&   r   rG   r   r   r   r   r   parser   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r      sj   
 
r   c                   @  s   e Zd ZU ded< eeejdd ddZded< d	Z	d
ed< eee
jdd dd	dZded< eedd dd dd	dZded< d	Zded< d	Zded< eeddd	dZd
ed< eeejdd dd	dZded< d	S )MetadataBlobPayloadEntryzSequence[StatusReport]status_reportsc                 C  r{   r|   r}   r   r'   r'   r(   r     r   z!MetadataBlobPayloadEntry.<lambda>r   r_   r   time_of_last_status_changeNrK   r   c                 C  r   r|   r   r   r'   r'   r(   r     r   r   r   r   c                 C  r   )Nc                 S  r   r'   r   r   r'   r'   r(   r     r   5MetadataBlobPayloadEntry.<lambda>.<locals>.<listcomp>r'   r   r'   r'   r(   r     r   c                 C  r   )Nc                 S  r   r'   r   r   r'   r'   r(   r     r   r   r'   r   r'   r'   r(   r     r   r   r   zOptional[MetadataStatement]metadata_statementz)Optional[Sequence[BiometricStatusReport]]biometric_status_reportsrogueListURLr?   rogue_list_urlc                 C  r{   r|   r   r   r'   r'   r(   r     r   r   rogue_list_hash)r#   r$   r%   r&   r   rG   r   r   r   r   r   r   r   r   r   r   r   r+   r   r   r'   r'   r'   r(   r      sF   
 
r   c                   @  sF   e Zd ZU ded< ded< eeejdd ddZd	ed
< ded< dS )MetadataBlobPayloadr/   r   r   noc                 C  r{   r|   r}   r   r'   r'   r(   r   (  r   zMetadataBlobPayload.<lambda>r   r_   r   next_updatez"Sequence[MetadataBlobPayloadEntry]entriesN)	r#   r$   r%   r&   r   rG   r   r   r   r'   r'   r'   r(   r   !  s   
 r   entryreturnr   c                 C  s   t dd | jD  S )zFilters out any revoked metadata entry.

    This filter will remove any metadata entry which has a status_report with
    the REVOKED status.
    c                 s  s    | ]	}|j tjkV  qd S r|   )rz   rh   rp   )r   rQ   r'   r'   r(   	<genexpr>8  s    
z!filter_revoked.<locals>.<genexpr>)anyr   )r   r'   r'   r(   filter_revoked2  s   
r   certificate_chainr   c                 C  s,   | j D ]}|jtjkr|j|v r dS qdS )zDenies any attestation that has a compromised attestation key.

    This filter checks the status reports of a metadata entry and ensures the
    attestation isn't signed by a key which is marked as compromised.
    FT)r   rz   rh   rl   r   )r   r   rQ   r'   r'   r(   "filter_attestation_key_compromised=  s   

r   _last_entryz.ContextVar[Optional[MetadataBlobPayloadEntry]]c                      sP   e Zd ZdZeedfd fddZd ddZd!ddZdd Z	d"ddZ
  ZS )#MdsAttestationVerifiera3  MDS3 implementation of an AttestationVerifier.

    The entry_filter is an optional predicate used to filter which metadata entries to
    include in the lookup for verification. By default, a filter that removes any
    entries that have a status report indicating the authenticator is REVOKED is used.
    See: filter_revoked

    The attestation_filter is an optional predicate used to filter metadata entries
    while performing attestation validation, and may take into account the
    Authenticators attestation trust_chain. By default, a filter that will fail any
    verification that has a trust_chain where one of the certificates is marked as
    compromised by the metadata statement is used.
    See: filter_attestation_key_compromised

    NOTE: The attestation_filter is not used when calling find_entry_by_aaguid nor
    find_entry_by_chain as no attestation is being verified!

    Setting either filter (including setting it to None) will replace it, removing
    the default behavior.

    :param blob: The MetadataBlobPayload to query for device metadata.
    :param entry_filter: An optional filter to exclude entries from lookup.
    :param attestation_filter: An optional filter to fail verification for a given
        attestation.
    :param attestation_types: A list of Attestation types to support.
    Nblobr   entry_filterOptional[EntryFilter]attestation_filterOptional[LookupFilter]r   Optional[Sequence[Attestation]]c                   s\   t  | |pdd | _ r fdd|jD n|j}dd |D | _dd |D | _d S )Nc                 S  s   dS )NTr'   )arS   r'   r'   r(   r   t  s    z1MdsAttestationVerifier.__init__.<locals>.<lambda>c                   s   g | ]} |r|qS r'   r'   r   er   r'   r(   r   x  r   z3MdsAttestationVerifier.__init__.<locals>.<listcomp>c                 S  s   i | ]	}|j r|j |qS r'   )r   r   r'   r'   r(   
<dictcomp>|  r   z3MdsAttestationVerifier.__init__.<locals>.<dictcomp>c                 S  s"   i | ]}|j pg D ]}||q	qS r'   )r   )r   r   skir'   r'   r(   r   }  s    )super__init___attestation_filterr   _aaguid_table
_ski_table)selfr   r   r   r   r   	__class__r   r(   r   k  s   zMdsAttestationVerifier.__init__r   r   r   "Optional[MetadataBlobPayloadEntry]c                 C  s   | j |S )zFind an entry by AAGUID.

        Returns a MetadataBlobPayloadEntry with a matching aaguid field, if found.
        This method does not take the attestation_filter into account.
        )r   get)r   r   r'   r'   r(   find_entry_by_aaguid  s   z+MdsAttestationVerifier.find_entry_by_aaguidr   r   c                 C  sF   |D ]}t |t }t j| j}|| jv r | j|   S qdS )a  Find an entry by trust chain.

        Returns a MetadataBlobPayloadEntry containing an
        attestationCertificateKeyIdentifier which matches one of the certificates in the
        given chain, if found.
        This method does not take the attestation_filter into account.
        N)r   load_der_x509_certificater   SubjectKeyIdentifierfrom_public_key
public_keydigestr   )r   r   dercertr   r'   r'   r(   find_entry_by_chain  s   

z*MdsAttestationVerifier.find_entry_by_chainc                 C  s   |j d usJ |j j}|rtd| d | |}ntd | |j}|rxtd|  | ||js?td d S |jsIt	d d S t
|jd t j}|jjD ]}t
|t j}||krot| |  S qXtd|  d S )	NzUsing AAGUID: z to look up metadataz*Using trust_path chain to look up metadatazFound entry: z-Matched entry did not pass attestation filterz8Matched entry has no metadata_statement, can't validate!z&No attestation root matching subject: )credential_datar   loggingdebugr   r   
trust_pathr   r   warningr   r   r   issuerr   subjectr   setloggerinfo)r   attestation_result	auth_datar   r   r  rootr  r'   r'   r(   	ca_lookup  sD   


z MdsAttestationVerifier.ca_lookupattestation_objectr   client_data_hashr+   c              	   C  s\   t d}z"z| || t  W W t | S  ty'   Y W t | dS w t | w )zLookup a Metadata entry based on an Attestation.

        Returns the first Metadata entry matching the given attestation and verifies it,
        including checking it against the attestation_filter.
        N)r   r	  verify_attestationr   resetr   )r   r  r  tokenr'   r'   r(   
find_entry  s   

z!MdsAttestationVerifier.find_entry)r   r   r   r   r   r   r   r   )r   r   r   r   )r   r   r   r   )r  r   r  r+   r   r   )r#   r$   r%   rx   r   r   r   r   r   r  r  __classcell__r'   r'   r   r(   r   O  s    


'r   r   r+   
trust_rootr   c           
      C  s   |  dd\}}t|}dd |dD \}}|durLdd |dg D }||g7 }t| t|d	 t }t	|d
 
| }	|	|| ntd t|S )a  Parse a FIDO MDS3 blob and verifies its signature.

    See https://fidoalliance.org/metadata/ for details on obtaining the blob, as well as
    the CA certificate used to sign it.

    The resulting MetadataBlobPayload can be used to lookup metadata entries for
    specific Authenticators, or used with the MdsAttestationVerifier to verify that the
    attestation from a WebAuthn registration is valid and included in the metadata blob.

    NOTE: If trust_root is None, the signature of the blob will NOT be verified!
       .r   c                 s  s    | ]
}t t|V  qd S r|   )jsonloadsr
   r   r'   r'   r(   r     s    zparse_blob.<locals>.<genexpr>Nc                 S  r   r'   r   )r   rc   r'   r'   r(   r     r   zparse_blob.<locals>.<listcomp>x5cr   algz?Parsing MDS blob without trust anchor, CONTENT IS NOT VERIFIED!)rsplitr
   splitr   r   r   r   r   r   for_namefrom_cryptography_keyr   verifyr
  warnr   	from_dict)
r   r  messagesignature_b64	signatureheaderpayloadchainleafr   r'   r'   r(   
parse_blob  s   


r+  )r   r   r   r   )r   r   r   r   r   r   )r   r+   r  r   r   r   )F
__future__r   webauthnr   r   attestationr   r   r   r	   utilsr
   r   coser   cryptographyr   cryptography.hazmat.backendsr   dataclassesr   r   enumr   r   datetimer   base64r   r   contextvarsr   typingr   r   r   r   r   r  r  	getLoggerr#   r
  r   r*   r-   r6   r=   rH   rJ   rP   rT   r]   r/   rh   ry   r   r   r   r   r   EntryFilterr+   LookupFilterr   r   r   r&   r   r+  r'   r'   r'   r(   <module>   sp   











	



8
%

 	