2
2
from dataclasses import dataclass , replace
3
3
from typing import Callable , FrozenSet , List , Optional , Union
4
4
5
+ import cryptography .exceptions
5
6
from cryptography import x509
6
7
from cryptography .hazmat .primitives .asymmetric import dsa , ec , rsa , utils
7
8
from cryptography .hazmat .primitives .asymmetric .padding import MGF1 , PSS , AsymmetricPadding , PKCS1v15
@@ -114,14 +115,20 @@ def _get_signature(self, root):
114
115
115
116
def _verify_signature_with_pubkey (
116
117
self ,
118
+ * ,
117
119
signed_info_c14n : bytes ,
118
120
raw_signature : bytes ,
119
- key_value : etree ._Element ,
120
- der_encoded_key_value : Optional [etree ._Element ],
121
121
signature_alg : SignatureMethod ,
122
+ key_value : Optional [etree ._Element ] = None ,
123
+ der_encoded_key_value : Optional [etree ._Element ] = None ,
124
+ signing_certificate : Optional [x509 .Certificate ] = None ,
122
125
) -> None :
123
126
if der_encoded_key_value is not None :
124
127
key = load_der_public_key (b64decode (der_encoded_key_value .text )) # type: ignore
128
+ elif signing_certificate is not None :
129
+ key = signing_certificate .public_key ()
130
+ elif key_value is None :
131
+ raise InvalidInput ("Expected one of key_value, der_encoded_key_value, or signing_certificate to be set" )
125
132
126
133
digest_alg_impl = digest_algorithm_implementations [signature_alg ]()
127
134
if signature_alg .name .startswith ("ECDSA_" ):
@@ -137,8 +144,8 @@ def _verify_signature_with_pubkey(
137
144
key = ecpn .public_key ()
138
145
elif not isinstance (key , ec .EllipticCurvePublicKey ):
139
146
raise InvalidInput ("DER encoded key value does not match specified signature algorithm" )
140
- dss_signature = self ._encode_dss_signature (raw_signature , key .key_size )
141
- key .verify (dss_signature , data = signed_info_c14n , signature_algorithm = ec .ECDSA (digest_alg_impl ))
147
+ signature_for_ecdsa = self ._encode_dss_signature (raw_signature , key .key_size )
148
+ key .verify (signature_for_ecdsa , data = signed_info_c14n , signature_algorithm = ec .ECDSA (digest_alg_impl ))
142
149
elif signature_alg .name .startswith ("DSA_" ):
143
150
if key_value is not None :
144
151
dsa_key_value = self ._find (key_value , "DSAKeyValue" )
@@ -167,7 +174,7 @@ def _verify_signature_with_pubkey(
167
174
padding = PSS (mgf = MGF1 (algorithm = digest_alg_impl ), salt_length = digest_alg_impl .digest_size )
168
175
key .verify (raw_signature , data = signed_info_c14n , padding = padding , algorithm = digest_alg_impl )
169
176
else :
170
- raise NotImplementedError ( )
177
+ raise InvalidInput ( f"Unsupported signature algorithm { signature_alg } " )
171
178
172
179
def _encode_dss_signature (self , raw_signature : bytes , key_size_bits : int ) -> bytes :
173
180
want_raw_signature_len = bits_to_bytes_unit (key_size_bits ) * 2
@@ -226,16 +233,6 @@ def _apply_transforms(self, payload, *, transforms_node: etree._Element, signatu
226
233
def get_cert_chain_verifier (self , ca_pem_file , ca_path ):
227
234
return X509CertChainVerifier (ca_pem_file = ca_pem_file , ca_path = ca_path )
228
235
229
- def _verify_signature_with_public_key_impl (self , * , signature , data , public_key , signature_alg_impl ):
230
- verify_args = dict (signature = signature , data = data )
231
- if isinstance (public_key , rsa .RSAPublicKey ):
232
- verify_args .update (padding = PKCS1v15 (), algorithm = signature_alg_impl )
233
- elif isinstance (public_key , dsa .DSAPublicKey ):
234
- verify_args .update (algorithm = signature_alg_impl )
235
- elif isinstance (public_key , ec .EllipticCurvePublicKey ):
236
- verify_args .update (signature_algorithm = ec .ECDSA (signature_alg_impl ))
237
- public_key .verify (** verify_args )
238
-
239
236
def verify (
240
237
self ,
241
238
data ,
@@ -406,17 +403,15 @@ def verify(
406
403
if subject_cn_from_signing_cert != cert_subject_name :
407
404
raise InvalidSignature ("Certificate subject common name mismatch" )
408
405
409
- if signature_alg .name .startswith ("ECDSA" ):
410
- raw_signature = self ._encode_dss_signature (raw_signature , signing_cert .public_key ().key_size )
411
-
412
- cert_public_key = signing_cert .public_key ()
413
- signature_alg_impl = digest_algorithm_implementations [signature_alg ]()
414
- self ._verify_signature_with_public_key_impl (
415
- signature = raw_signature ,
416
- data = signed_info_c14n ,
417
- public_key = cert_public_key ,
418
- signature_alg_impl = signature_alg_impl ,
419
- )
406
+ try :
407
+ self ._verify_signature_with_pubkey (
408
+ signed_info_c14n = signed_info_c14n ,
409
+ raw_signature = raw_signature ,
410
+ signing_certificate = signing_cert ,
411
+ signature_alg = signature_alg ,
412
+ )
413
+ except cryptography .exceptions .InvalidSignature as e :
414
+ raise InvalidSignature (f"Signature verification failed: { e } " )
420
415
421
416
# If both X509Data and KeyValue are present, match one against the other and raise an error on mismatch
422
417
if key_value is not None :
0 commit comments