@@ -78,6 +78,26 @@ def validate_private_key(value):
7878 raise ValidationError ('Could not load private key: {}' .format (e ))
7979
8080
81+ def validate_cert_pair (certificate , private_key ):
82+ # Load and validate the certificate and private key
83+ try :
84+ cert = validate_certificate (certificate )
85+ pkey = validate_private_key (private_key )
86+ except ValidationError as e :
87+ # The certificate and key should already have been validated
88+ raise SuspiciousOperation (e )
89+
90+ if pkey .type () == crypto .TYPE_RSA :
91+ # Compare modulus n, to the factors p and q
92+ priv_numbers = pkey .to_cryptography_key ().private_numbers ()
93+ pub_modulus = cert .get_pubkey ().to_cryptography_key ().public_numbers ().n
94+ if pub_modulus != (priv_numbers .p * priv_numbers .q ):
95+ raise ValidationError ('Certificate and private key do not match!' )
96+
97+ # Return tuple if everything went ok
98+ return (cert , pkey )
99+
100+
81101class Certificate (AuditedModel ):
82102 """
83103 Public and private key pair used to secure application traffic at the router.
@@ -114,13 +134,9 @@ def __str__(self):
114134 return self .name
115135
116136 def save (self , * args , ** kwargs ):
117- try :
118- certificate = validate_certificate (self .certificate )
119- # NOTE(bacongobbler): we want to load the key here to ensure that it is valid before
120- # saving it to the database.
121- validate_private_key (self .key )
122- except ValidationError as e :
123- raise SuspiciousOperation (e )
137+ # Validate the provided certificate and key pair and test for a mismatch
138+ certificate , _ = validate_cert_pair (self .certificate , self .key )
139+
124140 if not self .common_name :
125141 self .common_name = certificate .get_subject ().CN
126142
0 commit comments