+
     hE  c                  s  a  0 t $ ^ RIHt ^ RIt^ RIt^ RIHtHt ^ RIH	t	 ^ RI
HtHt ^ RIHt ^ RIHtHt ^ RIHtHtHtHt ^ R	IHt ^ R
IHt ^RIHtHtHtHt ^RI H!t! ^RI"H#t#H$t$ ^RI%H&t&H't' ]PP                  ! ])4      t*]! RRR7       ! R R]#4      4       t+]! RRR7       ! R R]#4      4       t,]! RRR7       ! R R]#4      4       t-]! RRR7       ! R R]#4      4       t.]! RRR7       ! R R]#4      4       t/]! RRR7       ! R R]#4      4       t0]! RRR7       ! R R]#4      4       t1]! RRR7       ! R  R!]#4      4       t2]! RRR7       ! R" R#]#4      4       t3]! RRR7       ! R$ R%]#4      4       t4] ! R& R']5]4      4       t6]! RRR7       ! R( R)]#4      4       t7]! RRR7       ! R* R+]#4      4       t8]! RRR7       ! R, R-]#4      4       t9]! RRR7       ! R. R/]#4      4       t:]! RRR7       ! R0 R1]#4      4       t;]]:.]<3,          t=]]:]]>,          .]<3,          t?R2 R3 lt@R4 R5 ltA]	! R64      tBR7]CR6&    ! R8 R9]4      tDR: R; ltER# )<i    )annotationsN)	b64decode	b64encode)
ContextVar)	dataclassfield)date)Enumunique)AnyCallableMappingSequence)x509)default_backend)AttestationAttestationVerifierUntrustedAttestationverify_x509_chain)CoseKey)_JsonDataObjectwebsafe_decode)AaguidAttestationObjectFT)ZeqZfrozenc                  s,    ] tR t^7t$ R]R&   R]R&   RtR# )VersionintZmajorZminor N__name__
__module____qualname____firstlineno____annotations____static_attributes__r       //usr/lib/python3.14/site-packages/fido2/mds3.pyr   r   7   s    JJr"   r   c                  s,    ] tR t^=t$ R]R&   R]R&   RtR# )RogueListEntrybytesZskr   r   r   Nr   r   r"   r#   r$   r$   =   s    I
Ir"   r$   c                  s^    ] tR t^Ct$ R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R
tR# )BiometricStatusReportr   Z
cert_levelstrZmodalityeffective_datecertification_descriptorcertificate_numbercertification_policy_version"certification_requirements_versionr   Nr   r   r"   r#   r&   r&   C   s*    OM!!"%%(++r"   r&   c                  sH    ] tR t^Nt$ R]R&   R]R&   RtR]R&   RtR]R&   RtR# )	CodeAccuracyDescriptorr   ZbaseZ
min_lengthN
int | Nonemax_retriesblock_slowdownr   r   r   r   r   r    r/   r0   r!   r   r"   r#   r-   r-   N   s     
IO"K"!%NJ%r"   r-   c                  s    ] tR t^Vt$ ]! R]! RR7      R7      tR]R&   ]! R]! RR7      R7      tR]R&   Rt	R	]R
&   Rt
R	]R&   RtR	]R&   RtR# )BiometricAccuracyDescriptorNZselfAttestedFRRZname)defaultmetadatazfloat | Noneself_attested_frrZselfAttestedFARself_attested_farr.   max_templatesr/   r0   r   )r   r   r   r   r   dictr6   r    r7   r8   r/   r0   r!   r   r"   r#   r2   r2   V   s^    &+t):;'|  ',t):;'|  !%M:$"K"!%NJ%r"   r2   c                  s>    ] tR t^ct$ R]R&   RtR]R&   RtR]R&   RtR# )PatternAccuracyDescriptorr   Zmin_complexityNr.   r/   r0   r   r1   r   r"   r#   r:   r:   c   s    "K"!%NJ%r"   r:   c                  sP    ] tR t^jt$ RtR]R&   RtR]R&   RtR]R&   RtR]R	&   R
t	R# )VerificationMethodDescriptorN
str | Noneuser_verification_methodzCodeAccuracyDescriptor | Noneca_descz"BiometricAccuracyDescriptor | Noneba_descz PatternAccuracyDescriptor | Nonepa_descr   )
r   r   r   r   r=   r    r>   r?   r@   r!   r   r"   r#   r;   r;   j   s.    +/j/-1G*126G/604G-4r"   r;   c                  s6    ] tR t^rt$ R]R&   R]R&   R]R&   RtR# )RgbPaletteEntryr   rZgbr   Nr   r   r"   r#   rA   rA   r   s    
F
F
Fr"   rA   c                  sl    ] tR t^yt$ R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R	tR
]R&   RtR	# )#DisplayPngCharacteristicsDescriptorr   ZwidthZheightZ	bit_depthZ
color_typeZcompressionZfilterZ	interlaceNz Sequence[RgbPaletteEntry] | Noneplter   )r   r   r   r   r    rE   r!   r   r"   r#   rD   rD   y   s1    JKNOKN-1D
*1r"   rD   c                  s    ] tR t^t$ ]! ]! RR7      R7      tR]R&   ]! ]! RR7      R7      tR]R&   R]R&   R]R	&   R]R
&   ]! ]! RR7      R7      t	R]R&   Rt
R# )EcdaaTrustAnchorZXr3   r5   r'   xZYycZsxZsyZG1Curveg1_curver   N)r   r   r   r   r   r9   rH   r    rI   rK   r!   r   r"   r#   rF   rF      sK    DcN+As+DcN+As+
FGG4Y#78Hc8r"   rF   c                  sV    ] tR t^tRtRtRtRtRtRt	Rt
RtR	tR
tRtRtRtRtRtRtRtR# )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_L3plusr   N)r   r   r   r   __doc__rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r!   r   r"   r#   rL   rL      s]    %-%N9!=!=#A )G9+3+3+3r"   rL   c                  s    ] tR t^t$ R]R&   ]! ]! ]P                  R R7      RR7      t	R]R&   Rt
R	]R
&   ]! ]! ]R R7      RR7      tR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR# )StatusReportrL   statusc                	"    V P                  4       # NZ	isoformatrH      &r#   <lambda>StatusReport.<lambda>   
    r"   Zdeserialize	serializeNr5   r4   zdate | Noner(   r.   authenticator_versionc                	s4    \        V 4      P                  4       # r`   r   Zdecoderb   rc   r#   rd   re      s    1ATATAVr"   bytes | Nonecertificater<   urlr)   r*   r+   r,   r   )r   r   r   r   r    r   r9   r   fromisoformatr(   rj   r   rm   rn   r)   r*   r+   r,   r!   r   r"   r#   r]   r]      s    "'**-
 #NK  )-:, %)7VW!K  C+/j/%)
)/3 *359&
9r"   r]   c                  sh    ] tR t^t$ ]! ]! RR7      R7      tR]R&   R]R&   RtR]R	&   Rt	R
]R&   Rt
R# )ExtensionDescriptorfail_if_unknownr3   rG   boolr'   ZidNr.   tagr<   datar   )r   r   r   r   r   r9   rq   r    rs   rt   r!   r   r"   r#   rp   rp      s0    !45F+GHOTHGCD*r"   rp   c                  sB   ] tR t^t$ R]R&   R]R&   R]R&   R]R&   R]R	&   ]! ]! R
 R7      R7      tR]R&   R]R&   R]R&   R]R&   R]R&   ]! ]! R R R7      R7      tR]R&   Rt	R]R&   Rt
R]R&   ]! ]! ]P                  R R7      RR7      tR]R&   ]! ]! R  R! R7      RR7      tR"]R#&   RtR$]R%&   RtR]R&&   RtR']R(&   RtR']R)&   RtR*]R+&   RtR*]R,&   RtR-]R.&   RtR]R/&   RtR]R0&   ]! ]! R1R27      RR7      tR3]R4&   RtR5]R6&   RtR]R7&   RtR8]R9&   RtR:]R;&   R<tR# )=MetadataStatementr'   Zdescriptionr   rj   ZschemazSequence[Version]ZupvzSequence[str]attestation_typesc           
     	sp    V  UUu. uF  q Uu. uF  p\        V4      NK  	  upNK  	  upp# u upi u uppi r`   )r9   )ZxssxsrH   s   &  r#   rd   MetadataStatement.<lambda>   s,    S,QSrr-Br!d1gr-BS,Q-B,Qs   2-22)rh   rG   z0Sequence[Sequence[VerificationMethodDescriptor]]user_verification_detailsZkey_protectionZmatcher_protectionZattachment_hintZ
tc_displayc                	sB    V  Uu. uF  p\        V4      NK  	  up# u upi r`   )r   rw   rH      & r#   rd   rx      s    "#="QIaL"#=#=s   c                	s^    V  Uu. uF  p\        V4      P                  4       NK  	  up# u upi r`   rk   rz   r{   r#   rd   rx      s#    !DA)A,"5"5"7!D!Ds   "*rg   Sequence[bytes]attestation_root_certificatesNr<   legal_headeraaidc                	    \        V 4      # r`   r'   rb   rc   r#   rd   rx          Ar"   ri   Aaguid | Noneaaguidc                	V    V  Uu. uF  p\         P                  V4      NK  	  up# u upi r`   r%   fromhexrz   r{   r#   rd   rx          b#AbEMM!$4b#A#A   &c                	J    V  Uu. uF  qP                  4       NK  	  up# u upi r`   Zhexrz   r{   r#   rd   rx          2!62a%%'2!6!6    Sequence[bytes] | None'attestation_certificate_key_identifierszMapping[str, str] | Nonealternative_descriptionsprotocol_familyzSequence[str] | Noneauthentication_algorithmspublic_key_alg_and_encodingszbool | Noneis_key_restricted#is_fresh_user_verification_requiredr.   crypto_strengthoperating_envtc_display_content_typeZtcDisplayPNGCharacteristicsr3   z4Sequence[DisplayPngCharacteristicsDescriptor] | Nonetc_display_png_characteristicsz!Sequence[EcdaaTrustAnchor] | Noneecdaa_trust_anchorsiconz$Sequence[ExtensionDescriptor] | Nonesupported_extensionszMapping[str, Any] | Noneauthenticator_get_infor   )r   r   r   r   r    r   r9   ry   r}   r~   r   r   parser   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r"   r#   ru   ru      s   K	$$RW QRSO  "!%%""5:=D
6!?   $L*#D*!&
 FM  GLA6
 G+-C  :>6="&OZ&6:3:9= "6=%){)7;';"&OZ& $M:$*.Z. 	89	 #< >B:AD*AE>E7;4;r"   ru   c                  st   ] tR t^t$ R]R&   ]! ]! ]P                  R R7      R7      t	R]R&   Rt
R	]R
&   ]! ]! ]P                  R R7      RR7      tR]R&   ]! ]! R R R7      RR7      tR]R&   RtR]R&   RtR]R&   ]! ]! RR7      RR7      tR	]R&   ]! ]! ]P&                  R R7      RR7      tR]R&   RtR# )MetadataBlobPayloadEntryzSequence[StatusReport]status_reportsc                	r_   r`   ra   rb   rc   r#   rd   !MetadataBlobPayloadEntry.<lambda>  rf   r"   rg   rG   r   time_of_last_status_changeNr<   r   c                	r   r`   r   rb   rc   r#   rd   r     r   r"   ri   r   r   c                	r   r`   r   rz   r{   r#   rd   r     r   r   c                	r   r`   r   rz   r{   r#   rd   r     r   r   r   r   zMetadataStatement | Nonemetadata_statementz&Sequence[BiometricStatusReport] | Nonebiometric_status_reportsZrogueListURLr3   rogue_list_urlc                	r_   r`   r   rb   rc   r#   rd   r     s
    r"   rl   rogue_list_hashr   )r   r   r   r   r    r   r9   r   ro   r   r   r   r   r   r   r   r   r   r%   r   r   r!   r   r"   r#   r   r      s    **',**-
(  D*!&
 FM  GLA6
 G+-C  4807GKDK!&.0ISW!XNJX$)'
 %O\ r"   r   c                  sx    ] tR tRt$ R]R&   R]R&   ]! ]! ]P                  R R7      R7      t	R	]R
&   R]R&   Rt
R# )MetadataBlobPayloadi  r'   r~   r   Znoc                	r_   r`   ra   rb   rc   r#   rd   ZMetadataBlobPayload.<lambda>&  rf   r"   rg   rG   r   next_updatez"Sequence[MetadataBlobPayloadEntry]entriesr   N)r   r   r   r   r    r   r9   r   ro   r   r!   r   r"   r#   r   r     s:    G**-
K  0/r"   r   c                    V ^8  d   QhRRRR/# )   entryr   returnrr   r   Zformat   "r#   __annotate__r   0  s      2 t r"   c                s    \         ;QJ d0    R V P                   4       F  '       g   K   R'       * # 	  R'       * # ! R V P                   4       4      '       * # )zFilters out any revoked metadata entry.

This filter will remove any metadata entry which has a status_report with
the REVOKED status.
c              3  sZ   "   T F!  qP                   \        P                  8H  x  K#  	  R # 5ir`   )r^   rL   rT   ).0rB   r{   r#   	<genexpr>Z!filter_revoked.<locals>.<genexpr>6  s"      9MA'///9Ms   )+TF)Zanyr   )r   rc   r#   filter_revokedr   0  sZ     s 9>9M9Mss  s  s 9>9M9M   r"   c               $    V ^8  d   QhRRRRRR/# )r   r   r   certificate_chainr|   r   rr   r   r   r   r#   r   r   ;  s$      #8G	r"   c                s    V P                    F8  pVP                  \        P                  8X  g   K$  VP                  V9   g   K7   R# 	  R# )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   r^   rL   rP   rm   )r   r   rB   s   && r#   "filter_attestation_key_compromisedr   ;  s<     !!88*EEE}} 11 " r"   _last_entryz+ContextVar[MetadataBlobPayloadEntry | None]c                  sf   a  ] tR tRtRt]]R3R V 3R llltR R ltR R	 lt	R
 t
R R ltRtV ;t# )MdsAttestationVerifieriM  a  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.
Nc               s(    V ^8  d   QhRRRRRRRR/# )	r   blobr   entry_filterzEntryFilter | Noneattestation_filterzLookupFilter | Nonerv   zSequence[Attestation] | Noner   r   r   r#   r   #MdsAttestationVerifier.__annotate__i  s2     
 
!
 )
 0	

 8
r"   c                	s  < \         SV `  V4       T;'       g    R  V n        V'       d,   VP                   Uu. uF  qR! V4      '       g   K  VNK  	  upMVP                  pV Uu/ uF#  qUP                  '       g   K  VP                  VbK%  	  upV n        V UUu/ uF"  pVP                  ;'       g    .  F  pWubK  	  K$  	  uppV n        R# u upi u upi u uppi )c                s    R # )Tr   )ZarC      &&r#   rd   Z1MdsAttestationVerifier.__init__.<locals>.<lambda>r  s    r"   N)Zsuper__init___attestation_filterr   r   _aaguid_tabler   
_ski_table)	selfr   r   r   rv   Zer   ski	__class__s	   &&&&&   r#   r   ZMdsAttestationVerifier.__init__i  s     	*+#5 $
 $
 	   81QQQ8 	
 4;G7ahhkahhk7G 
@@FFBF FF 
 9 H
s#   CC&C>CC4Cc               r   )r   r   r   r   MetadataBlobPayloadEntry | Noner   r   r   r#   r   r     s     . .6 .6U .r"   c                s8    V P                   P                  V4      # )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#   find_entry_by_aaguidZ+MdsAttestationVerifier.find_entry_by_aaguid  s     !!%%f--r"   c               r   )r   r   r|   r   r   r   r   r   r#   r   r     s      !0	(r"   c                s   V F~  p\         P                  ! V\        4       4      p\         P                  P	                  VP                  4       4      P                  pW@P                  9   g   Kk  V P                  V,          u # 	  R# )zFind 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   ZSubjectKeyIdentifierZfrom_public_key
public_keyZdigestr   )r   r   ZderZcertr   s   &&   r#   find_entry_by_chainZ*MdsAttestationVerifier.find_entry_by_chain  sd     %C11#7HID++;;DOO<MNUUCoo%s++	 %
 r"   c                	s   VP                   f   Q hVP                   P                  pV'       d-   \        P                  ! RV R24       V P	                  V4      pM1\        P                  ! R4       V P                  VP                  4      pV'       Ed4   \        P                  ! RV 24       V P                  WAP                  4      '       g   \        P                  ! R4       R # VP                  '       g   \        P                  ! R4       R # \        P                  ! VP                  R,          \        4       4      P                  pVP                  P                   FK  p\        P                  ! V\        4       4      P                  pWu8X  g   K4  \         P#                  V4       Vu # 	  \$        P'                  RV 24       R # )	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: i)Zcredential_datar   loggingZdebugr   r   Z
trust_pathr   r   Zwarningr   r   r   issuerr}   subjectr   setloggerZinfo)r   Zattestation_resultZ	auth_datar   r   r   Zrootr   s   &&&     r#   	ca_lookupZ MdsAttestationVerifier.ca_lookup  sk   ((444**11MMN6(2FGH--f5EMMFG,,-?-J-JKE5MMM%12 ++E3P3PQQMN +++N 33"--b1?3Df  00NN88/+'  $OOE*K O KK@IJr"   c               r   )r   attestation_objectr   client_data_hashr%   r   r   r   r   r   r#   r   r     s$     % %"3%GL%	(%r"   c                s$   \         P                  R4      p V P                  W4       \         P                  4       \         P	                  V4       #   \
         d     \         P	                  T4       R# i ; i  \         P	                  T4       i ; i)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   Zverify_attestationr   Zresetr   )r   r   r   Ztokens   &&& r#   
find_entryZ!MdsAttestationVerifier.find_entry  ss     %	%##$6I??$ e$ $ 	e$	 e$s#   $A A5A8 4A55A8 8B)r   r   r   )r   r   r   r   r\   r   r   r   r   r   r   r   r!   Z__classcell__)r      @r#   r   r   M  s7    < ,:2T:>
 
0."%N% %r"   r   c               r   )r   r   r%   
trust_rootrl   r   r   r   r   r   r#   r   r     s"     2 2U 2 29L 2r"   c                s:   V P                  R^4      w  r#\        V4      pR VP                  R4       4       w  rVVe   VP                  R. 4       Uu. uF  p\	        V4      NK  	  ppW.,          p\        V4       \        P                  ! V^ ,          \        4       4      p	\        P                  ! VR,          4      P                  V	P                  4       4      p
V
P                  W$4       M\        P                  R4       \         P#                  V4      # u upi )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!
s   .c              3  s`   "   T F$  p\         P                  ! \        V4      4      x  K&  	  R # 5ir`   )jsonZloadsr   )r   rH   r{   r#   r   Zparse_blob.<locals>.<genexpr>  s#     R>Qtzz."344>Qs   ,.Zx5cZalgz?Parsing MDS blob without trust anchor, CONTENT IS NOT VERIFIED!)Zrsplitr   Zsplitr   r   r   r   r   r   r   Zfor_nameZfrom_cryptography_keyr   Zverifyr   Zwarnr   Z	from_dict)r   r   ZmessageZsignature_b64Z	signatureZheaderZpayloadrJ   ZchainZleafr   s   &&         r#   
parse_blobr     s     "[[q1G}-IRgmmD>QROF'-zz%'<='<!1'<=%  --eAh8IJ%%fUm4JJOO

 	'-UV((11 >s   D)F__conditional_annotations__Z
__future__r    r   r   Zbase64r   r   Zcontextvarsr   Zdataclassesr   r   Zdatetimer   Zenumr   r   Ztypingr	   r
   r   r   Zcryptographyr   Zcryptography.hazmat.backendsr   Zattestationr   r   r   r   Zcoser   Zutilsr   r   Zwebauthnr   r   Z	getLoggerr   r   r   r$   r&   r-   r2   r:   r;   rA   rD   rF   r'   rL   r]   rp   ru   r   r   rr   ZEntryFilterr%   ZLookupFilterr   r   r   r    r   r   )r   r   r#   <module>r      s  8 # "   ' " (   3 3  8   2 /			8	$ eD!o  "
 eD!_  "
 eD!,O , ", eD!&_ & "& eD!	&/ 	& "	& eD!& & "& eD!5? 5 "5 eD!o  " eD!2/ 2 "2 eD!9 9 "9 4#t 4 4( eD!:? : ":* eD!/  " eD!5< 5< "5<p eD!    " F eD!	0/ 	0 "	0 0147818E?CTIJ <Fm;T8 TC%0 C%L2r"   