44from pyeudiw .trust .handler .interface import TrustHandlerInterface
55from pyeudiw .trust .model .trust_source import TrustSourceData , TrustEvaluationType
66from pyeudiw .trust .handler .exceptions import InvalidTrustHandlerConfiguration
7- from pyeudiw .jwk .parse import parse_pem , parse_x5c_keys , parse_certificate
7+ from pyeudiw .jwk .parse import parse_x5c_keys , parse_certificate
88from cryptojwt .jwk .jwk import key_from_jwk_dict
99from pyeudiw .x509 .verify import (
1010 PEM_cert_to_B64DER_cert ,
1111 to_DER_cert ,
1212 verify_x509_attestation_chain ,
1313 get_expiry_date_from_x5c ,
14- der_list_to_pem_list ,
15- pem_list_to_der_list ,
14+ to_pem_list ,
15+ to_der_list ,
1616 get_x509_info ,
1717 get_trust_anchor_from_x5c ,
1818 get_certificate_type
@@ -94,7 +94,7 @@ def __init__(
9494 logger .error (f"Invalid x509 leaf certificate using CA { k } . Unmatching private key, the chain will be removed" )
9595 continue
9696
97- chain = pem_list_to_der_list (v ) if type ( v [ 0 ]) == str and v [ 0 ]. startswith ( "-----BEGIN CERTIFICATE-----" ) else v
97+ chain = to_der_list (v )
9898
9999 if verify_x509_attestation_chain (chain ):
100100 self .relying_party_certificate_chains_by_ca [k ] = chain
@@ -104,79 +104,87 @@ def __init__(
104104
105105 self .private_keys = private_keys
106106
107- def extract_and_update_trust_materials (
108- self , issuer : str , trust_source : TrustSourceData
109- ) -> TrustSourceData :
110- # Return the first valid chain
111- for ca , chain in self .relying_party_certificate_chains_by_ca .items ():
112- if not verify_x509_attestation_chain (chain ):
113- logger .error (f"Invalid x509 certificate chain using CA { ca } . Chain validation failed, the chain will be removed" )
114- del self .relying_party_certificate_chains_by_ca [ca ]
115- continue
116-
117- exp = get_expiry_date_from_x5c (chain )
118-
119- trust_source .add_trust_param (
120- X509Handler ._TRUST_TYPE ,
121- TrustEvaluationType (
122- attribute_name = "x5c" ,
123- x5c = der_list_to_pem_list (chain ),
124- expiration_date = exp ,
125- jwks = self .private_keys ,
126- trust_handler_name = self .name ,
127- )
128- )
129-
130- return trust_source
131-
132- return trust_source
133-
134- def validate_trust_material (
135- self ,
136- x5c : list [str ],
137- trust_source : TrustSourceData ,
138- ) -> tuple [bool , TrustSourceData ]:
139- # TODO: qui c'è del lavoro veramente sporco da fare.
140- # Bisogna
141- # (1) normalizzare la rappresentazione della chain a DER; per fare questo bisogna fare inferenza se PEM o Base64+DER
142- # (2) normalizzare il salvatagggio della chain a PEM
143- # (3) incrociare le dita che MDOC non si sfasci...
107+ def _verify_chain (self , x5c : list [str ]) -> bool :
108+ """
109+ Verify the x5c chain.
110+ :param x5c: The x5c chain to verify.
111+ :return: True if the chain is valid, False otherwise.
112+ """
144113 der_chain = [to_DER_cert (cert ) for cert in x5c ]
145- pem_chain = der_list_to_pem_list (der_chain )
146114
147115 if len (der_chain ) > 1 and not verify_x509_attestation_chain (der_chain ):
148116 logger .error (f"Invalid x509 certificate chain. Chain validation failed" )
149- return False , trust_source
117+ return False
150118
151119 issuer = get_trust_anchor_from_x5c (der_chain )
152120
153121 if not issuer :
154122 logger .error ("Invalid x509 certificate chain. Issuer not found" )
155- return False , trust_source
123+ return False
156124
157125 if not issuer in self .certificate_authorities :
158126 logger .error ("Invalid x509 certificate chain. Issuer not found in the list of trusted CAs" )
159- return False , trust_source
127+ return False
160128
161- issuer_pem = self .certificate_authorities [issuer ]
129+ issuer_cert = self .certificate_authorities [issuer ]
162130
163131 try :
164- issuer_jwk = parse_pem ( issuer_pem )
165- chain_jwks = parse_x5c_keys (x5c )
132+ issuer_jwk = parse_certificate ( issuer_cert )
133+ chain_jwks = parse_x5c_keys (der_chain )
166134 except Exception as e :
167- logger .error ("Invalid x509 certificate chain. Parsing failed: {e}" )
168- return False , trust_source
135+ logger .error (f "Invalid x509 certificate chain. Parsing failed: { e } " )
136+ return False
169137
170138 if not issuer_jwk .thumbprint == chain_jwks [- 1 ].thumbprint :
171139 logger .error ("Invalid x509 certificate chain. Issuer thumbprint does not match" )
140+ return False
141+
142+ return True
143+
144+ def extract_and_update_trust_materials (
145+ self , issuer : str , trust_source : TrustSourceData
146+ ) -> TrustSourceData :
147+ # Return the first valid chain
148+ if issuer == self .client_id :
149+ for ca , chain in self .relying_party_certificate_chains_by_ca .items ():
150+ if not self ._verify_chain (chain ):
151+ logger .error (f"Invalid x509 certificate chain using CA { ca } . Chain will be ignored" )
152+ continue
153+
154+ exp = get_expiry_date_from_x5c (chain )
155+
156+ trust_source .add_trust_param (
157+ X509Handler ._TRUST_TYPE ,
158+ TrustEvaluationType (
159+ attribute_name = "x5c" ,
160+ x5c = to_pem_list (chain ),
161+ expiration_date = exp ,
162+ jwks = self .private_keys ,
163+ trust_handler_name = self .name ,
164+ )
165+ )
166+
167+ return trust_source
168+
169+ return trust_source
170+
171+ def validate_trust_material (
172+ self ,
173+ x5c : list [str ],
174+ trust_source : TrustSourceData ,
175+ ) -> tuple [bool , TrustSourceData ]:
176+ chain_jwks = parse_x5c_keys (x5c )
177+ valid = self ._verify_chain (x5c )
178+
179+ if not valid :
172180 return False , trust_source
173181
174182 trust_source .add_trust_param (
175183 "x509" ,
176184 TrustEvaluationType (
177185 attribute_name = self .get_handled_trust_material_name (),
178- x5c = pem_chain ,
179- expiration_date = get_expiry_date_from_x5c (der_chain ),
186+ x5c = to_pem_list ( x5c ) ,
187+ expiration_date = get_expiry_date_from_x5c (x5c ),
180188 jwks = chain_jwks ,
181189 trust_handler_name = self .name ,
182190 )
0 commit comments