1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """ 
 20  Utility functions for dealing with primes. 
 21  """ 
 22   
 23  from Crypto.Util import number 
 24   
 25  from paramiko import util 
 26  from paramiko.ssh_exception import SSHException 
 27   
 28   
 30      "primtive attempt at prime generation" 
 31      hbyte_mask = pow(2, bits % 8) - 1 
 32      while True: 
 33           
 34          x = randpool.get_bytes((bits+7) // 8) 
 35          if hbyte_mask > 0: 
 36              x = chr(ord(x[0]) & hbyte_mask) + x[1:] 
 37          n = util.inflate_long(x, 1) 
 38          n |= 1 
 39          n |= (1 << (bits - 1)) 
 40          while not number.isPrime(n): 
 41              n += 2 
 42          if util.bit_length(n) == bits: 
 43              break 
 44      return n 
  45   
 47      "returns a random # from 0 to N-1" 
 48      bits = util.bit_length(n-1) 
 49      bytes = (bits + 7) // 8 
 50      hbyte_mask = pow(2, bits % 8) - 1 
 51   
 52       
 53       
 54       
 55       
 56       
 57       
 58      while True: 
 59          x = rpool.get_bytes(bytes) 
 60          if hbyte_mask > 0: 
 61              x = chr(ord(x[0]) & hbyte_mask) + x[1:] 
 62          num = util.inflate_long(x, 1) 
 63          if num < n: 
 64              break 
 65      return num 
  66   
 67   
 69      """ 
 70      convenience object for holding the contents of the /etc/ssh/moduli file, 
 71      on systems that have such a file. 
 72      """ 
 73   
 75           
 76          self.pack = {} 
 77          self.discarded = [] 
 78          self.randpool = rpool 
  79   
 81          timestamp, mod_type, tests, tries, size, generator, modulus = line.split() 
 82          mod_type = int(mod_type) 
 83          tests = int(tests) 
 84          tries = int(tries) 
 85          size = int(size) 
 86          generator = int(generator) 
 87          modulus = long(modulus, 16) 
 88   
 89           
 90           
 91           
 92           
 93          if (mod_type < 2) or (tests < 4) or ((tests & 4) and (tests < 8) and (tries < 100)): 
 94              self.discarded.append((modulus, 'does not meet basic requirements')) 
 95              return 
 96          if generator == 0: 
 97              generator = 2 
 98   
 99           
100           
101           
102          bl = util.bit_length(modulus) 
103          if (bl != size) and (bl != size + 1): 
104              self.discarded.append((modulus, 'incorrectly reported bit length %d' % size)) 
105              return 
106          if bl not in self.pack: 
107              self.pack[bl] = [] 
108          self.pack[bl].append((generator, modulus)) 
 109   
111          """ 
112          @raise IOError: passed from any file operations that fail. 
113          """ 
114          self.pack = {} 
115          f = open(filename, 'r') 
116          for line in f: 
117              line = line.strip() 
118              if (len(line) == 0) or (line[0] == '#'): 
119                  continue 
120              try: 
121                  self._parse_modulus(line) 
122              except: 
123                  continue 
124          f.close() 
 125   
127          bitsizes = self.pack.keys() 
128          bitsizes.sort() 
129          if len(bitsizes) == 0: 
130              raise SSHException('no moduli available') 
131          good = -1 
132           
133          for b in bitsizes: 
134              if (b >= prefer) and (b < max) and ((b < good) or (good == -1)): 
135                  good = b 
136           
137          if good == -1: 
138              for b in bitsizes: 
139                  if (b >= min) and (b < max) and (b > good): 
140                      good = b 
141          if good == -1: 
142               
143               
144               
145               
146              good = bitsizes[0] 
147              if min > good: 
148                  good = bitsizes[-1] 
149           
150          n = _roll_random(self.randpool, len(self.pack[good])) 
151          return self.pack[good][n] 
  152