2424 valid = crypt.verify_signature(message, signature, cert)
2525
2626If you're going to verify many messages with the same certificate, you can use
27- :class:`Verifier `::
27+ :class:`RSAVerifier `::
2828
2929 cert = open('certs.pem').read()
30- verifier = crypt.Verifier .from_string(cert)
30+ verifier = crypt.RSAVerifier .from_string(cert)
3131 valid = verifier.verify(message, signature)
3232
3333
34- To sign messages use :class:`Signer ` with a private key::
34+ To sign messages use :class:`RSASigner ` with a private key::
3535
3636 private_key = open('private_key.pem').read()
37- signer = crypt.Signer (private_key)
37+ signer = crypt.RSASigner (private_key)
3838 signature = signer.sign(message)
3939
4040"""
41+ import abc
4142import io
4243import json
4344
@@ -77,23 +78,17 @@ def _bit_list_to_bytes(bit_list):
7778 byte_vals = bytearray ()
7879 for start in six .moves .xrange (0 , num_bits , 8 ):
7980 curr_bits = bit_list [start :start + 8 ]
80- char_val = sum (val * digit
81- for val , digit in six .moves .zip (_POW2 , curr_bits ))
81+ char_val = sum (
82+ val * digit for val , digit in six .moves .zip (_POW2 , curr_bits ))
8283 byte_vals .append (char_val )
8384 return bytes (byte_vals )
8485
8586
87+ @six .add_metaclass (abc .ABCMeta )
8688class Verifier (object ):
87- """This object is used to verify cryptographic signatures.
88-
89- Args:
90- public_key (rsa.key.PublicKey): The public key used to verify
91- signatures.
92- """
93-
94- def __init__ (self , public_key ):
95- self ._pubkey = public_key
89+ """Abstract base class for crytographic signature verifiers."""
9690
91+ @abc .abstractmethod
9792 def verify (self , message , signature ):
9893 """Verifies a message against a cryptographic signature.
9994
@@ -105,6 +100,24 @@ def verify(self, message, signature):
105100 bool: True if message was signed by the private key associated
106101 with the public key that this object was constructed with.
107102 """
103+ # pylint: disable=missing-raises-doc,redundant-returns-doc
104+ # (pylint doesn't recognize that this is abstract)
105+ raise NotImplementedError ('Verify must be implemented' )
106+
107+
108+ class RSAVerifier (Verifier ):
109+ """Verifies RSA cryptographic signatures using public keys.
110+
111+ Args:
112+ public_key (rsa.key.PublicKey): The public key used to verify
113+ signatures.
114+ """
115+
116+ def __init__ (self , public_key ):
117+ self ._pubkey = public_key
118+
119+ @_helpers .copy_docstring (Verifier )
120+ def verify (self , message , signature ):
108121 message = _helpers .to_bytes (message )
109122 try :
110123 return rsa .pkcs1 .verify (message , signature , self ._pubkey )
@@ -145,7 +158,7 @@ def from_string(cls, public_key):
145158
146159
147160def verify_signature (message , signature , certs ):
148- """Verify a cryptographic signature.
161+ """Verify an RSA cryptographic signature.
149162
150163 Checks that the provided ``signature`` was generated from ``bytes`` using
151164 the private key associated with the ``cert``.
@@ -163,27 +176,22 @@ def verify_signature(message, signature, certs):
163176 certs = [certs ]
164177
165178 for cert in certs :
166- verifier = Verifier .from_string (cert )
179+ verifier = RSAVerifier .from_string (cert )
167180 if verifier .verify (message , signature ):
168181 return True
169182 return False
170183
171184
185+ @six .add_metaclass (abc .ABCMeta )
172186class Signer (object ):
173- """Signs messages with a private key.
174-
175- Args:
176- private_key (rsa.key.PrivateKey): The private key to sign with.
177- key_id (str): Optional key ID used to identify this private key. This
178- can be useful to associate the private key with its associated
179- public key or certificate.
180- """
187+ """Abstract base class for cryptographic signers."""
181188
182- def __init__ (self , private_key , key_id = None ):
183- self ._key = private_key
184- self .key_id = key_id
189+ @abc .abstractproperty
190+ def key_id (self ):
185191 """Optional[str]: The key ID used to identify this private key."""
192+ raise NotImplementedError ('Key id must be implemented' )
186193
194+ @abc .abstractmethod
187195 def sign (self , message ):
188196 """Signs a message.
189197
@@ -193,6 +201,32 @@ def sign(self, message):
193201 Returns:
194202 bytes: The signature of the message.
195203 """
204+ # pylint: disable=missing-raises-doc,redundant-returns-doc
205+ # (pylint doesn't recognize that this is abstract)
206+ raise NotImplementedError ('Sign must be implemented' )
207+
208+
209+ class RSASigner (Signer ):
210+ """Signs messages with an RSA private key.
211+
212+ Args:
213+ private_key (rsa.key.PrivateKey): The private key to sign with.
214+ key_id (str): Optional key ID used to identify this private key. This
215+ can be useful to associate the private key with its associated
216+ public key or certificate.
217+ """
218+
219+ def __init__ (self , private_key , key_id = None ):
220+ self ._key = private_key
221+ self ._key_id = key_id
222+
223+ @property
224+ @_helpers .copy_docstring (Signer )
225+ def key_id (self ):
226+ return self ._key_id
227+
228+ @_helpers .copy_docstring (Signer )
229+ def sign (self , message ):
196230 message = _helpers .to_bytes (message )
197231 return rsa .pkcs1 .sign (message , self ._key , 'SHA-256' )
198232
0 commit comments