OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 # |
| 3 # Signature/PKCS1_PSS.py : PKCS#1 PPS |
| 4 # |
| 5 # =================================================================== |
| 6 # The contents of this file are dedicated to the public domain. To |
| 7 # the extent that dedication to the public domain is not available, |
| 8 # everyone is granted a worldwide, perpetual, royalty-free, |
| 9 # non-exclusive license to exercise all rights associated with the |
| 10 # contents of this file for any purpose whatsoever. |
| 11 # No rights are reserved. |
| 12 # |
| 13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 14 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 15 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 16 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 17 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 18 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 20 # SOFTWARE. |
| 21 # =================================================================== |
| 22 |
| 23 """RSA digital signature protocol with appendix according to PKCS#1 PSS. |
| 24 |
| 25 See RFC3447__ or the `original RSA Labs specification`__. |
| 26 |
| 27 This scheme is more properly called ``RSASSA-PSS``. |
| 28 |
| 29 For example, a sender may authenticate a message using SHA-1 and PSS like |
| 30 this: |
| 31 |
| 32 >>> from Crypto.Signature import PKCS1_PSS |
| 33 >>> from Crypto.Hash import SHA |
| 34 >>> from Crypto.PublicKey import RSA |
| 35 >>> from Crypto import Random |
| 36 >>> |
| 37 >>> message = 'To be signed' |
| 38 >>> key = RSA.importKey(open('privkey.der').read()) |
| 39 >>> h = SHA.new() |
| 40 >>> h.update(message) |
| 41 >>> signer = PKCS1_PSS.new(key) |
| 42 >>> signature = PKCS1_PSS.sign(key) |
| 43 |
| 44 At the receiver side, verification can be done like using the public part of |
| 45 the RSA key: |
| 46 |
| 47 >>> key = RSA.importKey(open('pubkey.der').read()) |
| 48 >>> h = SHA.new() |
| 49 >>> h.update(message) |
| 50 >>> verifier = PKCS1_PSS.new(key) |
| 51 >>> if verifier.verify(h, signature): |
| 52 >>> print "The signature is authentic." |
| 53 >>> else: |
| 54 >>> print "The signature is not authentic." |
| 55 |
| 56 :undocumented: __revision__, __package__ |
| 57 |
| 58 .. __: http://www.ietf.org/rfc/rfc3447.txt |
| 59 .. __: http://www.rsa.com/rsalabs/node.asp?id=2125 |
| 60 """ |
| 61 |
| 62 # Allow nested scopes in Python 2.1 |
| 63 # See http://oreilly.com/pub/a/python/2001/04/19/pythonnews.html |
| 64 from __future__ import nested_scopes |
| 65 |
| 66 __revision__ = "$Id$" |
| 67 __all__ = [ 'new', 'PSS_SigScheme' ] |
| 68 |
| 69 from Crypto.Util.py3compat import * |
| 70 if sys.version_info[0] == 2 and sys.version_info[1] == 1: |
| 71 from Crypto.Util.py21compat import * |
| 72 import Crypto.Util.number |
| 73 from Crypto.Util.number import ceil_shift, ceil_div, long_to_bytes |
| 74 from Crypto.Util.strxor import strxor |
| 75 |
| 76 class PSS_SigScheme: |
| 77 """This signature scheme can perform PKCS#1 PSS RSA signature or verificatio
n.""" |
| 78 |
| 79 def __init__(self, key, mgfunc, saltLen): |
| 80 """Initialize this PKCS#1 PSS signature scheme object. |
| 81 |
| 82 :Parameters: |
| 83 key : an RSA key object |
| 84 If a private half is given, both signature and verification are
possible. |
| 85 If a public half is given, only verification is possible. |
| 86 mgfunc : callable |
| 87 A mask generation function that accepts two parameters: a string
to |
| 88 use as seed, and the lenth of the mask to generate, in bytes. |
| 89 saltLen : int |
| 90 Length of the salt, in bytes. |
| 91 """ |
| 92 self._key = key |
| 93 self._saltLen = saltLen |
| 94 self._mgfunc = mgfunc |
| 95 |
| 96 def can_sign(self): |
| 97 """Return True if this cipher object can be used for signing messages.""
" |
| 98 return self._key.has_private() |
| 99 |
| 100 def sign(self, mhash): |
| 101 """Produce the PKCS#1 PSS signature of a message. |
| 102 |
| 103 This function is named ``RSASSA-PSS-SIGN``, and is specified in |
| 104 section 8.1.1 of RFC3447. |
| 105 |
| 106 :Parameters: |
| 107 mhash : hash object |
| 108 The hash that was carried out over the message. This is an objec
t |
| 109 belonging to the `Crypto.Hash` module. |
| 110 |
| 111 :Return: The PSS signature encoded as a string. |
| 112 :Raise ValueError: |
| 113 If the RSA key length is not sufficiently long to deal with the give
n |
| 114 hash algorithm. |
| 115 :Raise TypeError: |
| 116 If the RSA key has no private half. |
| 117 |
| 118 :attention: Modify the salt length and the mask generation function only |
| 119 if you know what you are doing. |
| 120 The receiver must use the same parameters too. |
| 121 """ |
| 122 # TODO: Verify the key is RSA |
| 123 |
| 124 randfunc = self._key._randfunc |
| 125 |
| 126 # Set defaults for salt length and mask generation function |
| 127 if self._saltLen == None: |
| 128 sLen = mhash.digest_size |
| 129 else: |
| 130 sLen = self._saltLen |
| 131 if self._mgfunc: |
| 132 mgf = self._mgfunc |
| 133 else: |
| 134 mgf = lambda x,y: MGF1(x,y,mhash) |
| 135 |
| 136 modBits = Crypto.Util.number.size(self._key.n) |
| 137 |
| 138 # See 8.1.1 in RFC3447 |
| 139 k = ceil_div(modBits,8) # Convert from bits to bytes |
| 140 # Step 1 |
| 141 em = EMSA_PSS_ENCODE(mhash, modBits-1, randfunc, mgf, sLen) |
| 142 # Step 2a (OS2IP) and 2b (RSASP1) |
| 143 m = self._key.decrypt(em) |
| 144 # Step 2c (I2OSP) |
| 145 S = bchr(0x00)*(k-len(m)) + m |
| 146 return S |
| 147 |
| 148 def verify(self, mhash, S): |
| 149 """Verify that a certain PKCS#1 PSS signature is authentic. |
| 150 |
| 151 This function checks if the party holding the private half of the given |
| 152 RSA key has really signed the message. |
| 153 |
| 154 This function is called ``RSASSA-PSS-VERIFY``, and is specified in secti
on |
| 155 8.1.2 of RFC3447. |
| 156 |
| 157 :Parameters: |
| 158 mhash : hash object |
| 159 The hash that was carried out over the message. This is an objec
t |
| 160 belonging to the `Crypto.Hash` module. |
| 161 S : string |
| 162 The signature that needs to be validated. |
| 163 |
| 164 :Return: True if verification is correct. False otherwise. |
| 165 """ |
| 166 # TODO: Verify the key is RSA |
| 167 |
| 168 # Set defaults for salt length and mask generation function |
| 169 if self._saltLen == None: |
| 170 sLen = mhash.digest_size |
| 171 else: |
| 172 sLen = self._saltLen |
| 173 if self._mgfunc: |
| 174 mgf = self._mgfunc |
| 175 else: |
| 176 mgf = lambda x,y: MGF1(x,y,mhash) |
| 177 |
| 178 modBits = Crypto.Util.number.size(self._key.n) |
| 179 |
| 180 # See 8.1.2 in RFC3447 |
| 181 k = ceil_div(modBits,8) # Convert from bits to bytes |
| 182 # Step 1 |
| 183 if len(S) != k: |
| 184 return False |
| 185 # Step 2a (O2SIP), 2b (RSAVP1), and partially 2c (I2OSP) |
| 186 # Note that signature must be smaller than the module |
| 187 # but RSA.py won't complain about it. |
| 188 # TODO: Fix RSA object; don't do it here. |
| 189 em = self._key.encrypt(S, 0)[0] |
| 190 # Step 2c |
| 191 emLen = ceil_div(modBits-1,8) |
| 192 em = bchr(0x00)*(emLen-len(em)) + em |
| 193 # Step 3 |
| 194 try: |
| 195 result = EMSA_PSS_VERIFY(mhash, em, modBits-1, mgf, sLen) |
| 196 except ValueError: |
| 197 return False |
| 198 # Step 4 |
| 199 return result |
| 200 |
| 201 def MGF1(mgfSeed, maskLen, hash): |
| 202 """Mask Generation Function, described in B.2.1""" |
| 203 T = b("") |
| 204 for counter in xrange(ceil_div(maskLen, hash.digest_size)): |
| 205 c = long_to_bytes(counter, 4) |
| 206 T = T + hash.new(mgfSeed + c).digest() |
| 207 assert(len(T)>=maskLen) |
| 208 return T[:maskLen] |
| 209 |
| 210 def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): |
| 211 """ |
| 212 Implement the ``EMSA-PSS-ENCODE`` function, as defined |
| 213 in PKCS#1 v2.1 (RFC3447, 9.1.1). |
| 214 |
| 215 The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M`` as input
, |
| 216 and hash it internally. Here, we expect that the message has already |
| 217 been hashed instead. |
| 218 |
| 219 :Parameters: |
| 220 mhash : hash object |
| 221 The hash object that holds the digest of the message being signed. |
| 222 emBits : int |
| 223 Maximum length of the final encoding, in bits. |
| 224 randFunc : callable |
| 225 An RNG function that accepts as only parameter an int, and returns |
| 226 a string of random bytes, to be used as salt. |
| 227 mgf : callable |
| 228 A mask generation function that accepts two parameters: a string to |
| 229 use as seed, and the lenth of the mask to generate, in bytes. |
| 230 sLen : int |
| 231 Length of the salt, in bytes. |
| 232 |
| 233 :Return: An ``emLen`` byte long string that encodes the hash |
| 234 (with ``emLen = \ceil(emBits/8)``). |
| 235 |
| 236 :Raise ValueError: |
| 237 When digest or salt length are too big. |
| 238 """ |
| 239 |
| 240 emLen = ceil_div(emBits,8) |
| 241 |
| 242 # Bitmask of digits that fill up |
| 243 lmask = 0 |
| 244 for i in xrange(8*emLen-emBits): |
| 245 lmask = lmask>>1 | 0x80 |
| 246 |
| 247 # Step 1 and 2 have been already done |
| 248 # Step 3 |
| 249 if emLen < mhash.digest_size+sLen+2: |
| 250 raise ValueError("Digest or salt length are too long for given key size.
") |
| 251 # Step 4 |
| 252 salt = b("") |
| 253 if randFunc and sLen>0: |
| 254 salt = randFunc(sLen) |
| 255 # Step 5 and 6 |
| 256 h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) |
| 257 # Step 7 and 8 |
| 258 db = bchr(0x00)*(emLen-sLen-mhash.digest_size-2) + bchr(0x01) + salt |
| 259 # Step 9 |
| 260 dbMask = mgf(h.digest(), emLen-mhash.digest_size-1) |
| 261 # Step 10 |
| 262 maskedDB = strxor(db,dbMask) |
| 263 # Step 11 |
| 264 maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:] |
| 265 # Step 12 |
| 266 em = maskedDB + h.digest() + bchr(0xBC) |
| 267 return em |
| 268 |
| 269 def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen): |
| 270 """ |
| 271 Implement the ``EMSA-PSS-VERIFY`` function, as defined |
| 272 in PKCS#1 v2.1 (RFC3447, 9.1.2). |
| 273 |
| 274 ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input, |
| 275 and hash it internally. Here, we expect that the message has already |
| 276 been hashed instead. |
| 277 |
| 278 :Parameters: |
| 279 mhash : hash object |
| 280 The hash object that holds the digest of the message to be verified. |
| 281 em : string |
| 282 The signature to verify, therefore proving that the sender really si
gned |
| 283 the message that was received. |
| 284 emBits : int |
| 285 Length of the final encoding (em), in bits. |
| 286 mgf : callable |
| 287 A mask generation function that accepts two parameters: a string to |
| 288 use as seed, and the lenth of the mask to generate, in bytes. |
| 289 sLen : int |
| 290 Length of the salt, in bytes. |
| 291 |
| 292 :Return: 0 if the encoding is consistent, 1 if it is inconsistent. |
| 293 |
| 294 :Raise ValueError: |
| 295 When digest or salt length are too big. |
| 296 """ |
| 297 |
| 298 emLen = ceil_div(emBits,8) |
| 299 |
| 300 # Bitmask of digits that fill up |
| 301 lmask = 0 |
| 302 for i in xrange(8*emLen-emBits): |
| 303 lmask = lmask>>1 | 0x80 |
| 304 |
| 305 # Step 1 and 2 have been already done |
| 306 # Step 3 |
| 307 if emLen < mhash.digest_size+sLen+2: |
| 308 return False |
| 309 # Step 4 |
| 310 if ord(em[-1:])!=0xBC: |
| 311 return False |
| 312 # Step 5 |
| 313 maskedDB = em[:emLen-mhash.digest_size-1] |
| 314 h = em[emLen-mhash.digest_size-1:-1] |
| 315 # Step 6 |
| 316 if lmask & bord(em[0]): |
| 317 return False |
| 318 # Step 7 |
| 319 dbMask = mgf(h, emLen-mhash.digest_size-1) |
| 320 # Step 8 |
| 321 db = strxor(maskedDB, dbMask) |
| 322 # Step 9 |
| 323 db = bchr(bord(db[0]) & ~lmask) + db[1:] |
| 324 # Step 10 |
| 325 if not db.startswith(bchr(0x00)*(emLen-mhash.digest_size-sLen-2) + bchr(0x01
)): |
| 326 return False |
| 327 # Step 11 |
| 328 salt = b("") |
| 329 if sLen: salt = db[-sLen:] |
| 330 # Step 12 and 13 |
| 331 hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() |
| 332 # Step 14 |
| 333 if h!=hp: |
| 334 return False |
| 335 return True |
| 336 |
| 337 def new(key, mgfunc=None, saltLen=None): |
| 338 """Return a signature scheme object `PSS_SigScheme` that |
| 339 can be used to perform PKCS#1 PSS signature or verification. |
| 340 |
| 341 :Parameters: |
| 342 key : RSA key object |
| 343 The key to use to sign or verify the message. This is a `Crypto.PublicKe
y.RSA` object. |
| 344 Signing is only possible if *key* is a private RSA key. |
| 345 mgfunc : callable |
| 346 A mask generation function that accepts two parameters: a string to |
| 347 use as seed, and the lenth of the mask to generate, in bytes. |
| 348 If not specified, the standard MGF1 is used. |
| 349 saltLen : int |
| 350 Length of the salt, in bytes. If not specified, it matches the output |
| 351 size of the hash function. |
| 352 |
| 353 """ |
| 354 return PSS_SigScheme(key, mgfunc, saltLen) |
| 355 |
OLD | NEW |