blob: ffdf2cc3a1a5239d8b01645dc1bfb3ee24fee462 [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
A R Karthick307483c2016-06-06 17:05:19 -070017## This file is part of Scapy
18## See http://www.secdev.org/projects/scapy for more informations
19## Copyright (C) Arnaud Ebalard <arno@natisbad.org>
20## This program is published under a GPLv2 license
21
22"""
23Cryptographic certificates.
24"""
25
26import os, sys, math, struct, random
27from scapy.utils import strxor
28from scapy_ssl_tls.ssl_tls_crypto import x509_extract_pubkey_from_der
29try:
30 HAS_HASHLIB=True
31 import hashlib
32except:
33 HAS_HASHLIB=False
34
35from Crypto.PublicKey import *
36from Crypto.Cipher import *
37from Crypto.Hash import *
38from Crypto.Util import number
39
40# Maximum allowed size in bytes for a certificate file, to avoid
41# loading huge file when importing a cert
42MAX_KEY_SIZE=50*1024
43
44#####################################################################
45# Some helpers
46#####################################################################
47
48def warning(m):
49 print "WARNING: %s" % m
50
51def randstring(l):
52 """
53 Returns a random string of length l (l >= 0)
54 """
55 tmp = map(lambda x: struct.pack("B", random.randrange(0, 256, 1)), [""]*l)
56 return "".join(tmp)
57
58def zerofree_randstring(l):
59 """
60 Returns a random string of length l (l >= 0) without zero in it.
61 """
62 tmp = map(lambda x: struct.pack("B", random.randrange(1, 256, 1)), [""]*l)
63 return "".join(tmp)
64
65def strand(s1, s2):
66 """
67 Returns the binary AND of the 2 provided strings s1 and s2. s1 and s2
68 must be of same length.
69 """
70 return "".join(map(lambda x,y:chr(ord(x)&ord(y)), s1, s2))
71
72# OS2IP function defined in RFC 3447 for octet string to integer conversion
73def pkcs_os2ip(x):
74 """
75 Accepts a byte string as input parameter and return the associated long
76 value:
77
78 Input : x octet string to be converted
79
80 Output: x corresponding nonnegative integer
81
82 Reverse function is pkcs_i2osp()
83 """
84 return number.bytes_to_long(x)
85
86# IP2OS function defined in RFC 3447 for octet string to integer conversion
87def pkcs_i2osp(x,xLen):
88 """
89 Converts a long (the first parameter) to the associated byte string
90 representation of length l (second parameter). Basically, the length
91 parameters allow the function to perform the associated padding.
92
93 Input : x nonnegative integer to be converted
94 xLen intended length of the resulting octet string
95
96 Output: x corresponding nonnegative integer
97
98 Reverse function is pkcs_os2ip().
99 """
100 z = number.long_to_bytes(x)
101 padlen = max(0, xLen-len(z))
102 return '\x00'*padlen + z
103
104# for every hash function a tuple is provided, giving access to
105# - hash output length in byte
106# - associated hash function that take data to be hashed as parameter
107# XXX I do not provide update() at the moment.
108# - DER encoding of the leading bits of digestInfo (the hash value
109# will be concatenated to create the complete digestInfo).
110#
111# Notes:
112# - MD4 asn.1 value should be verified. Also, as stated in
113# PKCS#1 v2.1, MD4 should not be used.
114# - hashlib is available from http://code.krypto.org/python/hashlib/
115# - 'tls' one is the concatenation of both md5 and sha1 hashes used
116# by SSL/TLS when signing/verifying things
117_hashFuncParams = {
118 "md2" : (16,
119 lambda x: MD2.new(x).digest(),
120 '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10'),
121 "md4" : (16,
122 lambda x: MD4.new(x).digest(),
123 '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04\x05\x00\x04\x10'), # is that right ?
124 "md5" : (16,
125 lambda x: MD5.new(x).digest(),
126 '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10'),
127 "sha1" : (20,
128 lambda x: SHA.new(x).digest(),
129 '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'),
130 "tls" : (36,
131 lambda x: MD5.new(x).digest() + SHA.new(x).digest(),
132 '') }
133
134if HAS_HASHLIB:
135 _hashFuncParams["sha224"] = (28,
136 lambda x: hashlib.sha224(x).digest(),
137 '\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c')
138 _hashFuncParams["sha256"] = (32,
139 lambda x: hashlib.sha256(x).digest(),
140 '\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20')
141 _hashFuncParams["sha384"] = (48,
142 lambda x: hashlib.sha384(x).digest(),
143 '\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30')
144 _hashFuncParams["sha512"] = (64,
145 lambda x: hashlib.sha512(x).digest(),
146 '\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40')
147else:
148 warning("hashlib support is not available. Consider installing it")
149 warning("if you need sha224, sha256, sha384 and sha512 algs.")
150
151def pkcs_mgf1(mgfSeed, maskLen, h):
152 """
153 Implements generic MGF1 Mask Generation function as described in
154 Appendix B.2.1 of RFC 3447. The hash function is passed by name.
155 valid values are 'md2', 'md4', 'md5', 'sha1', 'tls, 'sha256',
156 'sha384' and 'sha512'. Returns None on error.
157
158 Input:
159 mgfSeed: seed from which mask is generated, an octet string
160 maskLen: intended length in octets of the mask, at most 2^32 * hLen
161 hLen (see below)
162 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
163 'sha256', 'sha384'). hLen denotes the length in octets of
164 the hash function output.
165
166 Output:
167 an octet string of length maskLen
168 """
169
170 # steps are those of Appendix B.2.1
171 if not _hashFuncParams.has_key(h):
172 warning("pkcs_mgf1: invalid hash (%s) provided")
173 return None
174 hLen = _hashFuncParams[h][0]
175 hFunc = _hashFuncParams[h][1]
176 if maskLen > 2**32 * hLen: # 1)
177 warning("pkcs_mgf1: maskLen > 2**32 * hLen")
178 return None
179 T = "" # 2)
180 maxCounter = math.ceil(float(maskLen) / float(hLen)) # 3)
181 counter = 0
182 while counter < maxCounter:
183 C = pkcs_i2osp(counter, 4)
184 T += hFunc(mgfSeed + C)
185 counter += 1
186 return T[:maskLen]
187
188
189def pkcs_emsa_pss_encode(M, emBits, h, mgf, sLen):
190 """
191 Implements EMSA-PSS-ENCODE() function described in Sect. 9.1.1 of RFC 3447
192
193 Input:
194 M : message to be encoded, an octet string
195 emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM),
196 where EM is the encoded message, output of the function.
197 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
198 'sha256', 'sha384'). hLen denotes the length in octets of
199 the hash function output.
200 mgf : the mask generation function f : seed, maskLen -> mask
201 sLen : intended length in octets of the salt
202
203 Output:
204 encoded message, an octet string of length emLen = ceil(emBits/8)
205
206 On error, None is returned.
207 """
208
209 # 1) is not done
210 hLen = _hashFuncParams[h][0] # 2)
211 hFunc = _hashFuncParams[h][1]
212 mHash = hFunc(M)
213 emLen = int(math.ceil(emBits/8.))
214 if emLen < hLen + sLen + 2: # 3)
215 warning("encoding error (emLen < hLen + sLen + 2)")
216 return None
217 salt = randstring(sLen) # 4)
218 MPrime = '\x00'*8 + mHash + salt # 5)
219 H = hFunc(MPrime) # 6)
220 PS = '\x00'*(emLen - sLen - hLen - 2) # 7)
221 DB = PS + '\x01' + salt # 8)
222 dbMask = mgf(H, emLen - hLen - 1) # 9)
223 maskedDB = strxor(DB, dbMask) # 10)
224 l = (8*emLen - emBits)/8 # 11)
225 rem = 8*emLen - emBits - 8*l # additionnal bits
226 andMask = l*'\x00'
227 if rem:
228 j = chr(reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem))))
229 andMask += j
230 l += 1
231 maskedDB = strand(maskedDB[:l], andMask) + maskedDB[l:]
232 EM = maskedDB + H + '\xbc' # 12)
233 return EM # 13)
234
235
236def pkcs_emsa_pss_verify(M, EM, emBits, h, mgf, sLen):
237 """
238 Implements EMSA-PSS-VERIFY() function described in Sect. 9.1.2 of RFC 3447
239
240 Input:
241 M : message to be encoded, an octet string
242 EM : encoded message, an octet string of length emLen = ceil(emBits/8)
243 emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM)
244 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
245 'sha256', 'sha384'). hLen denotes the length in octets of
246 the hash function output.
247 mgf : the mask generation function f : seed, maskLen -> mask
248 sLen : intended length in octets of the salt
249
250 Output:
251 True if the verification is ok, False otherwise.
252 """
253
254 # 1) is not done
255 hLen = _hashFuncParams[h][0] # 2)
256 hFunc = _hashFuncParams[h][1]
257 mHash = hFunc(M)
258 emLen = int(math.ceil(emBits/8.)) # 3)
259 if emLen < hLen + sLen + 2:
260 return False
261 if EM[-1] != '\xbc': # 4)
262 return False
263 l = emLen - hLen - 1 # 5)
264 maskedDB = EM[:l]
265 H = EM[l:l+hLen]
266 l = (8*emLen - emBits)/8 # 6)
267 rem = 8*emLen - emBits - 8*l # additionnal bits
268 andMask = l*'\xff'
269 if rem:
270 val = reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem)))
271 j = chr(~val & 0xff)
272 andMask += j
273 l += 1
274 if strand(maskedDB[:l], andMask) != '\x00'*l:
275 return False
276 dbMask = mgf(H, emLen - hLen - 1) # 7)
277 DB = strxor(maskedDB, dbMask) # 8)
278 l = (8*emLen - emBits)/8 # 9)
279 rem = 8*emLen - emBits - 8*l # additionnal bits
280 andMask = l*'\x00'
281 if rem:
282 j = chr(reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem))))
283 andMask += j
284 l += 1
285 DB = strand(DB[:l], andMask) + DB[l:]
286 l = emLen - hLen - sLen - 1 # 10)
287 if DB[:l] != '\x00'*(l-1) + '\x01':
288 return False
289 salt = DB[-sLen:] # 11)
290 MPrime = '\x00'*8 + mHash + salt # 12)
291 HPrime = hFunc(MPrime) # 13)
292 return H == HPrime # 14)
293
294
295def pkcs_emsa_pkcs1_v1_5_encode(M, emLen, h): # section 9.2 of RFC 3447
296 """
297 Implements EMSA-PKCS1-V1_5-ENCODE() function described in Sect.
298 9.2 of RFC 3447.
299
300 Input:
301 M : message to be encode, an octet string
302 emLen: intended length in octets of the encoded message, at least
303 tLen + 11, where tLen is the octet length of the DER encoding
304 T of a certain value computed during the encoding operation.
305 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
306 'sha256', 'sha384'). hLen denotes the length in octets of
307 the hash function output.
308
309 Output:
310 encoded message, an octet string of length emLen
311
312 On error, None is returned.
313 """
314 hLen = _hashFuncParams[h][0] # 1)
315 hFunc = _hashFuncParams[h][1]
316 H = hFunc(M)
317 hLeadingDigestInfo = _hashFuncParams[h][2] # 2)
318 T = hLeadingDigestInfo + H
319 tLen = len(T)
320 if emLen < tLen + 11: # 3)
321 warning("pkcs_emsa_pkcs1_v1_5_encode: intended encoded message length too short")
322 return None
323 PS = '\xff'*(emLen - tLen - 3) # 4)
324 EM = '\x00' + '\x01' + PS + '\x00' + T # 5)
325 return EM # 6)
326
327
328#####################################################################
329# Public Key Cryptography related stuff
330#####################################################################
331
332class _EncryptAndVerify:
333 ### Below are encryption methods
334
335 def _rsaep(self, m):
336 """
337 Internal method providing raw RSA encryption, i.e. simple modular
338 exponentiation of the given message representative 'm', a long
339 between 0 and n-1.
340
341 This is the encryption primitive RSAEP described in PKCS#1 v2.1,
342 i.e. RFC 3447 Sect. 5.1.1.
343
344 Input:
345 m: message representative, a long between 0 and n-1, where
346 n is the key modulus.
347
348 Output:
349 ciphertext representative, a long between 0 and n-1
350
351 Not intended to be used directly. Please, see encrypt() method.
352 """
353
354 n = self.modulus
355 if type(m) is int:
356 m = long(m)
357 if type(m) is not long or m > n-1:
358 warning("Key._rsaep() expects a long between 0 and n-1")
359 return None
360
361 return self.key.encrypt(m, "")[0]
362
363
364 def _rsaes_pkcs1_v1_5_encrypt(self, M):
365 """
366 Implements RSAES-PKCS1-V1_5-ENCRYPT() function described in section
367 7.2.1 of RFC 3447.
368
369 Input:
370 M: message to be encrypted, an octet string of length mLen, where
371 mLen <= k - 11 (k denotes the length in octets of the key modulus)
372
373 Output:
374 ciphertext, an octet string of length k
375
376 On error, None is returned.
377 """
378
379 # 1) Length checking
380 mLen = len(M)
381 k = self.modulusLen / 8
382 if mLen > k - 11:
383 warning("Key._rsaes_pkcs1_v1_5_encrypt(): message too "
384 "long (%d > %d - 11)" % (mLen, k))
385 return None
386
387 # 2) EME-PKCS1-v1_5 encoding
388 PS = zerofree_randstring(k - mLen - 3) # 2.a)
389 EM = '\x00' + '\x02' + PS + '\x00' + M # 2.b)
390
391 # 3) RSA encryption
392 m = pkcs_os2ip(EM) # 3.a)
393 c = self._rsaep(m) # 3.b)
394 C = pkcs_i2osp(c, k) # 3.c)
395
396 return C # 4)
397
398
399 def _rsaes_oaep_encrypt(self, M, h=None, mgf=None, L=None):
400 """
401 Internal method providing RSAES-OAEP-ENCRYPT as defined in Sect.
402 7.1.1 of RFC 3447. Not intended to be used directly. Please, see
403 encrypt() method for type "OAEP".
404
405
406 Input:
407 M : message to be encrypted, an octet string of length mLen
408 where mLen <= k - 2*hLen - 2 (k denotes the length in octets
409 of the RSA modulus and hLen the length in octets of the hash
410 function output)
411 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
412 'sha256', 'sha384'). hLen denotes the length in octets of
413 the hash function output. 'sha1' is used by default if not
414 provided.
415 mgf: the mask generation function f : seed, maskLen -> mask
416 L : optional label to be associated with the message; the default
417 value for L, if not provided is the empty string
418
419 Output:
420 ciphertext, an octet string of length k
421
422 On error, None is returned.
423 """
424 # The steps below are the one described in Sect. 7.1.1 of RFC 3447.
425 # 1) Length Checking
426 # 1.a) is not done
427 mLen = len(M)
428 if h is None:
429 h = "sha1"
430 if not _hashFuncParams.has_key(h):
431 warning("Key._rsaes_oaep_encrypt(): unknown hash function %s.", h)
432 return None
433 hLen = _hashFuncParams[h][0]
434 hFun = _hashFuncParams[h][1]
435 k = self.modulusLen / 8
436 if mLen > k - 2*hLen - 2: # 1.b)
437 warning("Key._rsaes_oaep_encrypt(): message too long.")
438 return None
439
440 # 2) EME-OAEP encoding
441 if L is None: # 2.a)
442 L = ""
443 lHash = hFun(L)
444 PS = '\x00'*(k - mLen - 2*hLen - 2) # 2.b)
445 DB = lHash + PS + '\x01' + M # 2.c)
446 seed = randstring(hLen) # 2.d)
447 if mgf is None: # 2.e)
448 mgf = lambda x,y: pkcs_mgf1(x,y,h)
449 dbMask = mgf(seed, k - hLen - 1)
450 maskedDB = strxor(DB, dbMask) # 2.f)
451 seedMask = mgf(maskedDB, hLen) # 2.g)
452 maskedSeed = strxor(seed, seedMask) # 2.h)
453 EM = '\x00' + maskedSeed + maskedDB # 2.i)
454
455 # 3) RSA Encryption
456 m = pkcs_os2ip(EM) # 3.a)
457 c = self._rsaep(m) # 3.b)
458 C = pkcs_i2osp(c, k) # 3.c)
459
460 return C # 4)
461
462
463 def encrypt(self, m, t=None, h=None, mgf=None, L=None):
464 """
465 Encrypt message 'm' using 't' encryption scheme where 't' can be:
466
467 - None: the message 'm' is directly applied the RSAEP encryption
468 primitive, as described in PKCS#1 v2.1, i.e. RFC 3447
469 Sect 5.1.1. Simply put, the message undergo a modular
470 exponentiation using the public key. Additionnal method
471 parameters are just ignored.
472
473 - 'pkcs': the message 'm' is applied RSAES-PKCS1-V1_5-ENCRYPT encryption
474 scheme as described in section 7.2.1 of RFC 3447. In that
475 context, other parameters ('h', 'mgf', 'l') are not used.
476
477 - 'oaep': the message 'm' is applied the RSAES-OAEP-ENCRYPT encryption
478 scheme, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect
479 7.1.1. In that context,
480
481 o 'h' parameter provides the name of the hash method to use.
482 Possible values are "md2", "md4", "md5", "sha1", "tls",
483 "sha224", "sha256", "sha384" and "sha512". if none is provided,
484 sha1 is used.
485
486 o 'mgf' is the mask generation function. By default, mgf
487 is derived from the provided hash function using the
488 generic MGF1 (see pkcs_mgf1() for details).
489
490 o 'L' is the optional label to be associated with the
491 message. If not provided, the default value is used, i.e
492 the empty string. No check is done on the input limitation
493 of the hash function regarding the size of 'L' (for
494 instance, 2^61 - 1 for SHA-1). You have been warned.
495 """
496
497 if t is None: # Raw encryption
498 m = pkcs_os2ip(m)
499 c = self._rsaep(m)
500 return pkcs_i2osp(c, self.modulusLen/8)
501
502 elif t == "pkcs":
503 return self._rsaes_pkcs1_v1_5_encrypt(m)
504
505 elif t == "oaep":
506 return self._rsaes_oaep_encrypt(m, h, mgf, L)
507
508 else:
509 warning("Key.encrypt(): Unknown encryption type (%s) provided" % t)
510 return None
511
512 ### Below are verification related methods
513
514 def _rsavp1(self, s):
515 """
516 Internal method providing raw RSA verification, i.e. simple modular
517 exponentiation of the given signature representative 'c', an integer
518 between 0 and n-1.
519
520 This is the signature verification primitive RSAVP1 described in
521 PKCS#1 v2.1, i.e. RFC 3447 Sect. 5.2.2.
522
523 Input:
524 s: signature representative, an integer between 0 and n-1,
525 where n is the key modulus.
526
527 Output:
528 message representative, an integer between 0 and n-1
529
530 Not intended to be used directly. Please, see verify() method.
531 """
532 return self._rsaep(s)
533
534 def _rsassa_pss_verify(self, M, S, h=None, mgf=None, sLen=None):
535 """
536 Implements RSASSA-PSS-VERIFY() function described in Sect 8.1.2
537 of RFC 3447
538
539 Input:
540 M: message whose signature is to be verified
541 S: signature to be verified, an octet string of length k, where k
542 is the length in octets of the RSA modulus n.
543
544 Output:
545 True is the signature is valid. False otherwise.
546 """
547
548 # Set default parameters if not provided
549 if h is None: # By default, sha1
550 h = "sha1"
551 if not _hashFuncParams.has_key(h):
552 warning("Key._rsassa_pss_verify(): unknown hash function "
553 "provided (%s)" % h)
554 return False
555 if mgf is None: # use mgf1 with underlying hash function
556 mgf = lambda x,y: pkcs_mgf1(x, y, h)
557 if sLen is None: # use Hash output length (A.2.3 of RFC 3447)
558 hLen = _hashFuncParams[h][0]
559 sLen = hLen
560
561 # 1) Length checking
562 modBits = self.modulusLen
563 k = modBits / 8
564 if len(S) != k:
565 return False
566
567 # 2) RSA verification
568 s = pkcs_os2ip(S) # 2.a)
569 m = self._rsavp1(s) # 2.b)
570 emLen = math.ceil((modBits - 1) / 8.) # 2.c)
571 EM = pkcs_i2osp(m, emLen)
572
573 # 3) EMSA-PSS verification
574 Result = pkcs_emsa_pss_verify(M, EM, modBits - 1, h, mgf, sLen)
575
576 return Result # 4)
577
578
579 def _rsassa_pkcs1_v1_5_verify(self, M, S, h):
580 """
581 Implements RSASSA-PKCS1-v1_5-VERIFY() function as described in
582 Sect. 8.2.2 of RFC 3447.
583
584 Input:
585 M: message whose signature is to be verified, an octet string
586 S: signature to be verified, an octet string of length k, where
587 k is the length in octets of the RSA modulus n
588 h: hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
589 'sha256', 'sha384').
590
591 Output:
592 True if the signature is valid. False otherwise.
593 """
594
595 # 1) Length checking
596 k = self.modulusLen / 8
597 if len(S) != k:
598 warning("invalid signature (len(S) != k)")
599 return False
600
601 # 2) RSA verification
602 s = pkcs_os2ip(S) # 2.a)
603 m = self._rsavp1(s) # 2.b)
604 EM = pkcs_i2osp(m, k) # 2.c)
605
606 # 3) EMSA-PKCS1-v1_5 encoding
607 EMPrime = pkcs_emsa_pkcs1_v1_5_encode(M, k, h)
608 if EMPrime is None:
609 warning("Key._rsassa_pkcs1_v1_5_verify(): unable to encode.")
610 return False
611
612 # 4) Comparison
613 return EM == EMPrime
614
615
616 def verify(self, M, S, t=None, h=None, mgf=None, sLen=None):
617 """
618 Verify alleged signature 'S' is indeed the signature of message 'M' using
619 't' signature scheme where 't' can be:
620
621 - None: the alleged signature 'S' is directly applied the RSAVP1 signature
622 primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect
623 5.2.1. Simply put, the provided signature is applied a moular
624 exponentiation using the public key. Then, a comparison of the
625 result is done against 'M'. On match, True is returned.
626 Additionnal method parameters are just ignored.
627
628 - 'pkcs': the alleged signature 'S' and message 'M' are applied
629 RSASSA-PKCS1-v1_5-VERIFY signature verification scheme as
630 described in Sect. 8.2.2 of RFC 3447. In that context,
631 the hash function name is passed using 'h'. Possible values are
632 "md2", "md4", "md5", "sha1", "tls", "sha224", "sha256", "sha384"
633 and "sha512". If none is provided, sha1 is used. Other additionnal
634 parameters are ignored.
635
636 - 'pss': the alleged signature 'S' and message 'M' are applied
637 RSASSA-PSS-VERIFY signature scheme as described in Sect. 8.1.2.
638 of RFC 3447. In that context,
639
640 o 'h' parameter provides the name of the hash method to use.
641 Possible values are "md2", "md4", "md5", "sha1", "tls", "sha224",
642 "sha256", "sha384" and "sha512". if none is provided, sha1
643 is used.
644
645 o 'mgf' is the mask generation function. By default, mgf
646 is derived from the provided hash function using the
647 generic MGF1 (see pkcs_mgf1() for details).
648
649 o 'sLen' is the length in octet of the salt. You can overload the
650 default value (the octet length of the hash value for provided
651 algorithm) by providing another one with that parameter.
652 """
653 if t is None: # RSAVP1
654 S = pkcs_os2ip(S)
655 n = self.modulus
656 if S > n-1:
657 warning("Signature to be verified is too long for key modulus")
658 return False
659 m = self._rsavp1(S)
660 if m is None:
661 return False
662 l = int(math.ceil(math.log(m, 2) / 8.)) # Hack
663 m = pkcs_i2osp(m, l)
664 return M == m
665
666 elif t == "pkcs": # RSASSA-PKCS1-v1_5-VERIFY
667 if h is None:
668 h = "sha1"
669 return self._rsassa_pkcs1_v1_5_verify(M, S, h)
670
671 elif t == "pss": # RSASSA-PSS-VERIFY
672 return self._rsassa_pss_verify(M, S, h, mgf, sLen)
673
674 else:
675 warning("Key.verify(): Unknown signature type (%s) provided" % t)
676 return None
677
678class _DecryptAndSignMethods:
679 ### Below are decryption related methods. Encryption ones are inherited
680 ### from PubKey
681
682 def _rsadp(self, c):
683 """
684 Internal method providing raw RSA decryption, i.e. simple modular
685 exponentiation of the given ciphertext representative 'c', a long
686 between 0 and n-1.
687
688 This is the decryption primitive RSADP described in PKCS#1 v2.1,
689 i.e. RFC 3447 Sect. 5.1.2.
690
691 Input:
692 c: ciphertest representative, a long between 0 and n-1, where
693 n is the key modulus.
694
695 Output:
696 ciphertext representative, a long between 0 and n-1
697
698 Not intended to be used directly. Please, see encrypt() method.
699 """
700
701 n = self.modulus
702 if type(c) is int:
703 c = long(c)
704 if type(c) is not long or c > n-1:
705 warning("Key._rsaep() expects a long between 0 and n-1")
706 return None
707
708 return self.key.decrypt(c)
709
710
711 def _rsaes_pkcs1_v1_5_decrypt(self, C):
712 """
713 Implements RSAES-PKCS1-V1_5-DECRYPT() function described in section
714 7.2.2 of RFC 3447.
715
716 Input:
717 C: ciphertext to be decrypted, an octet string of length k, where
718 k is the length in octets of the RSA modulus n.
719
720 Output:
721 an octet string of length k at most k - 11
722
723 on error, None is returned.
724 """
725
726 # 1) Length checking
727 cLen = len(C)
728 k = self.modulusLen / 8
729 if cLen != k or k < 11:
730 warning("Key._rsaes_pkcs1_v1_5_decrypt() decryption error "
731 "(cLen != k or k < 11)")
732 return None
733
734 # 2) RSA decryption
735 c = pkcs_os2ip(C) # 2.a)
736 m = self._rsadp(c) # 2.b)
737 EM = pkcs_i2osp(m, k) # 2.c)
738
739 # 3) EME-PKCS1-v1_5 decoding
740
741 # I am aware of the note at the end of 7.2.2 regarding error
742 # conditions reporting but the one provided below are for _local_
743 # debugging purposes. --arno
744
745 if EM[0] != '\x00':
746 warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error "
747 "(first byte is not 0x00)")
748 return None
749
750 if EM[1] != '\x02':
751 warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error "
752 "(second byte is not 0x02)")
753 return None
754
755 tmp = EM[2:].split('\x00', 1)
756 if len(tmp) != 2:
757 warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error "
758 "(no 0x00 to separate PS from M)")
759 return None
760
761 PS, M = tmp
762 if len(PS) < 8:
763 warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error "
764 "(PS is less than 8 byte long)")
765 return None
766
767 return M # 4)
768
769
770 def _rsaes_oaep_decrypt(self, C, h=None, mgf=None, L=None):
771 """
772 Internal method providing RSAES-OAEP-DECRYPT as defined in Sect.
773 7.1.2 of RFC 3447. Not intended to be used directly. Please, see
774 encrypt() method for type "OAEP".
775
776
777 Input:
778 C : ciphertext to be decrypted, an octet string of length k, where
779 k = 2*hLen + 2 (k denotes the length in octets of the RSA modulus
780 and hLen the length in octets of the hash function output)
781 h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
782 'sha256', 'sha384'). 'sha1' is used if none is provided.
783 mgf: the mask generation function f : seed, maskLen -> mask
784 L : optional label whose association with the message is to be
785 verified; the default value for L, if not provided is the empty
786 string.
787
788 Output:
789 message, an octet string of length k mLen, where mLen <= k - 2*hLen - 2
790
791 On error, None is returned.
792 """
793 # The steps below are the one described in Sect. 7.1.2 of RFC 3447.
794
795 # 1) Length Checking
796 # 1.a) is not done
797 if h is None:
798 h = "sha1"
799 if not _hashFuncParams.has_key(h):
800 warning("Key._rsaes_oaep_decrypt(): unknown hash function %s.", h)
801 return None
802 hLen = _hashFuncParams[h][0]
803 hFun = _hashFuncParams[h][1]
804 k = self.modulusLen / 8
805 cLen = len(C)
806 if cLen != k: # 1.b)
807 warning("Key._rsaes_oaep_decrypt(): decryption error. "
808 "(cLen != k)")
809 return None
810 if k < 2*hLen + 2:
811 warning("Key._rsaes_oaep_decrypt(): decryption error. "
812 "(k < 2*hLen + 2)")
813 return None
814
815 # 2) RSA decryption
816 c = pkcs_os2ip(C) # 2.a)
817 m = self._rsadp(c) # 2.b)
818 EM = pkcs_i2osp(m, k) # 2.c)
819
820 # 3) EME-OAEP decoding
821 if L is None: # 3.a)
822 L = ""
823 lHash = hFun(L)
824 Y = EM[:1] # 3.b)
825 if Y != '\x00':
826 warning("Key._rsaes_oaep_decrypt(): decryption error. "
827 "(Y is not zero)")
828 return None
829 maskedSeed = EM[1:1+hLen]
830 maskedDB = EM[1+hLen:]
831 if mgf is None:
832 mgf = lambda x,y: pkcs_mgf1(x, y, h)
833 seedMask = mgf(maskedDB, hLen) # 3.c)
834 seed = strxor(maskedSeed, seedMask) # 3.d)
835 dbMask = mgf(seed, k - hLen - 1) # 3.e)
836 DB = strxor(maskedDB, dbMask) # 3.f)
837
838 # I am aware of the note at the end of 7.1.2 regarding error
839 # conditions reporting but the one provided below are for _local_
840 # debugging purposes. --arno
841
842 lHashPrime = DB[:hLen] # 3.g)
843 tmp = DB[hLen:].split('\x01', 1)
844 if len(tmp) != 2:
845 warning("Key._rsaes_oaep_decrypt(): decryption error. "
846 "(0x01 separator not found)")
847 return None
848 PS, M = tmp
849 if PS != '\x00'*len(PS):
850 warning("Key._rsaes_oaep_decrypt(): decryption error. "
851 "(invalid padding string)")
852 return None
853 if lHash != lHashPrime:
854 warning("Key._rsaes_oaep_decrypt(): decryption error. "
855 "(invalid hash)")
856 return None
857 return M # 4)
858
859
860 def decrypt(self, C, t=None, h=None, mgf=None, L=None):
861 """
862 Decrypt ciphertext 'C' using 't' decryption scheme where 't' can be:
863
864 - None: the ciphertext 'C' is directly applied the RSADP decryption
865 primitive, as described in PKCS#1 v2.1, i.e. RFC 3447
866 Sect 5.1.2. Simply, put the message undergo a modular
867 exponentiation using the private key. Additionnal method
868 parameters are just ignored.
869
870 - 'pkcs': the ciphertext 'C' is applied RSAES-PKCS1-V1_5-DECRYPT
871 decryption scheme as described in section 7.2.2 of RFC 3447.
872 In that context, other parameters ('h', 'mgf', 'l') are not
873 used.
874
875 - 'oaep': the ciphertext 'C' is applied the RSAES-OAEP-DECRYPT decryption
876 scheme, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect
877 7.1.2. In that context,
878
879 o 'h' parameter provides the name of the hash method to use.
880 Possible values are "md2", "md4", "md5", "sha1", "tls",
881 "sha224", "sha256", "sha384" and "sha512". if none is provided,
882 sha1 is used by default.
883
884 o 'mgf' is the mask generation function. By default, mgf
885 is derived from the provided hash function using the
886 generic MGF1 (see pkcs_mgf1() for details).
887
888 o 'L' is the optional label to be associated with the
889 message. If not provided, the default value is used, i.e
890 the empty string. No check is done on the input limitation
891 of the hash function regarding the size of 'L' (for
892 instance, 2^61 - 1 for SHA-1). You have been warned.
893 """
894 if t is None:
895 C = pkcs_os2ip(C)
896 c = self._rsadp(C)
897 l = int(math.ceil(math.log(c, 2) / 8.)) # Hack
898 return pkcs_i2osp(c, l)
899
900 elif t == "pkcs":
901 return self._rsaes_pkcs1_v1_5_decrypt(C)
902
903 elif t == "oaep":
904 return self._rsaes_oaep_decrypt(C, h, mgf, L)
905
906 else:
907 warning("Key.decrypt(): Unknown decryption type (%s) provided" % t)
908 return None
909
910 ### Below are signature related methods. Verification ones are inherited from
911 ### PubKey
912
913 def _rsasp1(self, m):
914 """
915 Internal method providing raw RSA signature, i.e. simple modular
916 exponentiation of the given message representative 'm', an integer
917 between 0 and n-1.
918
919 This is the signature primitive RSASP1 described in PKCS#1 v2.1,
920 i.e. RFC 3447 Sect. 5.2.1.
921
922 Input:
923 m: message representative, an integer between 0 and n-1, where
924 n is the key modulus.
925
926 Output:
927 signature representative, an integer between 0 and n-1
928
929 Not intended to be used directly. Please, see sign() method.
930 """
931 return self._rsadp(m)
932
933
934 def _rsassa_pss_sign(self, M, h=None, mgf=None, sLen=None):
935 """
936 Implements RSASSA-PSS-SIGN() function described in Sect. 8.1.1 of
937 RFC 3447.
938
939 Input:
940 M: message to be signed, an octet string
941
942 Output:
943 signature, an octet string of length k, where k is the length in
944 octets of the RSA modulus n.
945
946 On error, None is returned.
947 """
948
949 # Set default parameters if not provided
950 if h is None: # By default, sha1
951 h = "sha1"
952 if not _hashFuncParams.has_key(h):
953 warning("Key._rsassa_pss_sign(): unknown hash function "
954 "provided (%s)" % h)
955 return None
956 if mgf is None: # use mgf1 with underlying hash function
957 mgf = lambda x,y: pkcs_mgf1(x, y, h)
958 if sLen is None: # use Hash output length (A.2.3 of RFC 3447)
959 hLen = _hashFuncParams[h][0]
960 sLen = hLen
961
962 # 1) EMSA-PSS encoding
963 modBits = self.modulusLen
964 k = modBits / 8
965 EM = pkcs_emsa_pss_encode(M, modBits - 1, h, mgf, sLen)
966 if EM is None:
967 warning("Key._rsassa_pss_sign(): unable to encode")
968 return None
969
970 # 2) RSA signature
971 m = pkcs_os2ip(EM) # 2.a)
972 s = self._rsasp1(m) # 2.b)
973 S = pkcs_i2osp(s, k) # 2.c)
974
975 return S # 3)
976
977
978 def _rsassa_pkcs1_v1_5_sign(self, M, h):
979 """
980 Implements RSASSA-PKCS1-v1_5-SIGN() function as described in
981 Sect. 8.2.1 of RFC 3447.
982
983 Input:
984 M: message to be signed, an octet string
985 h: hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls'
986 'sha256', 'sha384').
987
988 Output:
989 the signature, an octet string.
990 """
991
992 # 1) EMSA-PKCS1-v1_5 encoding
993 k = self.modulusLen / 8
994 EM = pkcs_emsa_pkcs1_v1_5_encode(M, k, h)
995 if EM is None:
996 warning("Key._rsassa_pkcs1_v1_5_sign(): unable to encode")
997 return None
998
999 # 2) RSA signature
1000 m = pkcs_os2ip(EM) # 2.a)
1001 s = self._rsasp1(m) # 2.b)
1002 S = pkcs_i2osp(s, k) # 2.c)
1003
1004 return S # 3)
1005
1006
1007 def sign(self, M, t=None, h=None, mgf=None, sLen=None):
1008 """
1009 Sign message 'M' using 't' signature scheme where 't' can be:
1010
1011 - None: the message 'M' is directly applied the RSASP1 signature
1012 primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect
1013 5.2.1. Simply put, the message undergo a modular exponentiation
1014 using the private key. Additionnal method parameters are just
1015 ignored.
1016
1017 - 'pkcs': the message 'M' is applied RSASSA-PKCS1-v1_5-SIGN signature
1018 scheme as described in Sect. 8.2.1 of RFC 3447. In that context,
1019 the hash function name is passed using 'h'. Possible values are
1020 "md2", "md4", "md5", "sha1", "tls", "sha224", "sha256", "sha384"
1021 and "sha512". If none is provided, sha1 is used. Other additionnal
1022 parameters are ignored.
1023
1024 - 'pss' : the message 'M' is applied RSASSA-PSS-SIGN signature scheme as
1025 described in Sect. 8.1.1. of RFC 3447. In that context,
1026
1027 o 'h' parameter provides the name of the hash method to use.
1028 Possible values are "md2", "md4", "md5", "sha1", "tls", "sha224",
1029 "sha256", "sha384" and "sha512". if none is provided, sha1
1030 is used.
1031
1032 o 'mgf' is the mask generation function. By default, mgf
1033 is derived from the provided hash function using the
1034 generic MGF1 (see pkcs_mgf1() for details).
1035
1036 o 'sLen' is the length in octet of the salt. You can overload the
1037 default value (the octet length of the hash value for provided
1038 algorithm) by providing another one with that parameter.
1039 """
1040
1041 if t is None: # RSASP1
1042 M = pkcs_os2ip(M)
1043 n = self.modulus
1044 if M > n-1:
1045 warning("Message to be signed is too long for key modulus")
1046 return None
1047 s = self._rsasp1(M)
1048 if s is None:
1049 return None
1050 return pkcs_i2osp(s, self.modulusLen/8)
1051
1052 elif t == "pkcs": # RSASSA-PKCS1-v1_5-SIGN
1053 if h is None:
1054 h = "sha1"
1055 return self._rsassa_pkcs1_v1_5_sign(M, h)
1056
1057 elif t == "pss": # RSASSA-PSS-SIGN
1058 return self._rsassa_pss_sign(M, h, mgf, sLen)
1059
1060 else:
1061 warning("Key.sign(): Unknown signature type (%s) provided" % t)
1062 return None
1063
1064class Key(_DecryptAndSignMethods, _EncryptAndVerify):
1065
1066 def __init__(self, pem_data):
1067 self.key = RSA.importKey(pem_data)
1068 self.modulus = self.key.key.n
1069 self.modulusLen = self.key.key.size() + 1
1070 self.privExp = self.key.key.d
1071 self.pubExp = self.key.key.e
1072 self.prime1 = self.key.key.p
1073 self.prime2 = self.key.key.q
1074 self.exponent1 = 0
1075 self.exponent2 = 0
1076 self.coefficient = self.key.key.u