示例#1
0
 def verify_ssh_sig(self, data, msg):
     if msg.get_string() != 'ssh-rsa':
         return False
     sig = util.inflate_long(msg.get_string(), True)
     # verify the signature by SHA'ing the data and encrypting it using the
     # public key.  some wackiness ensues where we "pkcs1imify" the 20-byte
     # hash into a string as long as the RSA key.
     hash_obj = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()), True)
     rsa = RSA.construct((long(self.n), long(self.e)))
     return rsa.verify(hash_obj, (sig,))
示例#2
0
 def verify_ssh_sig(self, data, msg):
     if msg.get_string() != 'ssh-rsa':
         return False
     sig = util.inflate_long(msg.get_string(), True)
     # verify the signature by SHA'ing the data and encrypting it using the
     # public key.  some wackiness ensues where we "pkcs1imify" the 20-byte
     # hash into a string as long as the RSA key.
     hash_obj = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()),
                                  True)
     rsa = RSA.construct((long(self.n), long(self.e)))
     return rsa.verify(hash_obj, (sig, ))
示例#3
0
    def verify_ssh_sig(self, data, msg):
        if len(str(msg)) == 40:
            # spies.com bug: signature has no header
            sig = str(msg)
        else:
            kind = msg.get_string()
            if kind != 'ssh-dss':
                return 0
            sig = msg.get_string()

        # pull out (r, s) which are NOT encoded as mpints
        sigR = util.inflate_long(sig[:20], 1)
        sigS = util.inflate_long(sig[20:], 1)
        sigM = util.inflate_long(SHA.new(data).digest(), 1)

        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
        return dss.verify(sigM, (sigR, sigS))
示例#4
0
    def get_mpint(self):
        """
        Fetch a long int (mpint) from the stream.

        @return: an arbitrary-length integer.
        @rtype: long
        """
        return util.inflate_long(self.get_string())
示例#5
0
    def get_mpint(self):
        """
        Fetch a long int (mpint) from the stream.

        @return: an arbitrary-length integer.
        @rtype: long
        """
        return util.inflate_long(self.get_string())
示例#6
0
文件: ber.py 项目: zhangmh2/ssh
 def decode_next(self):
     if self.idx >= len(self.content):
         return None
     ident = ord(self.content[self.idx])
     self.idx += 1
     if (ident & 31) == 31:
         # identifier > 30
         ident = 0
         while self.idx < len(self.content):
             t = ord(self.content[self.idx])
             self.idx += 1
             ident = (ident << 7) | (t & 0x7f)
             if not (t & 0x80):
                 break
     if self.idx >= len(self.content):
         return None
     # now fetch length
     size = ord(self.content[self.idx])
     self.idx += 1
     if size & 0x80:
         # more complimicated...
         # FIXME: theoretically should handle indefinite-length (0x80)
         t = size & 0x7f
         if self.idx + t > len(self.content):
             return None
         size = util.inflate_long(self.content[self.idx:self.idx + t], True)
         self.idx += t
     if self.idx + size > len(self.content):
         # can't fit
         return None
     data = self.content[self.idx:self.idx + size]
     self.idx += size
     # now switch on id
     if ident == 0x30:
         # sequence
         return self.decode_sequence(data)
     elif ident == 2:
         # int
         return util.inflate_long(data)
     else:
         # 1: boolean (00 false, otherwise true)
         raise BERException('Unknown ber encoding type %d (robey is lazy)' %
                            ident)
示例#7
0
 def decode_next(self):
     if self.idx >= len(self.content):
         return None
     ident = ord(self.content[self.idx])
     self.idx += 1
     if (ident & 31) == 31:
         # identifier > 30
         ident = 0
         while self.idx < len(self.content):
             t = ord(self.content[self.idx])
             self.idx += 1
             ident = (ident << 7) | (t & 0x7f)
             if not (t & 0x80):
                 break
     if self.idx >= len(self.content):
         return None
     # now fetch length
     size = ord(self.content[self.idx])
     self.idx += 1
     if size & 0x80:
         # more complimicated...
         # FIXME: theoretically should handle indefinite-length (0x80)
         t = size & 0x7f
         if self.idx + t > len(self.content):
             return None
         size = util.inflate_long(self.content[self.idx : self.idx + t], True)
         self.idx += t
     if self.idx + size > len(self.content):
         # can't fit
         return None
     data = self.content[self.idx : self.idx + size]
     self.idx += size
     # now switch on id
     if ident == 0x30:
         # sequence
         return self.decode_sequence(data)
     elif ident == 2:
         # int
         return util.inflate_long(data)
     else:
         # 1: boolean (00 false, otherwise true)
         raise BERException('Unknown ber encoding type %d (robey is lazy)' % ident)
示例#8
0
 def sign_ssh_data(self, rng, data):
     digest = SHA.new(data).digest()
     dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
     # generate a suitable k
     qsize = len(util.deflate_long(self.q, 0))
     while True:
         k = util.inflate_long(rng.read(qsize), 1)
         if (k > 2) and (k < self.q):
             break
     r, s = dss.sign(util.inflate_long(digest, 1), k)
     m = Message()
     m.add_string('ssh-dss')
     # apparently, in rare cases, r or s may be shorter than 20 bytes!
     rstr = util.deflate_long(r, 0)
     sstr = util.deflate_long(s, 0)
     if len(rstr) < 20:
         rstr = '\x00' * (20 - len(rstr)) + rstr
     if len(sstr) < 20:
         sstr = '\x00' * (20 - len(sstr)) + sstr
     m.add_string(rstr + sstr)
     return m
示例#9
0
 def _generate_x(self):
     # generate an "x" (1 < x < q), where q is (p-1)/2.
     # p is a 128-byte (1024-bit) number, where the first 64 bits are 1.
     # therefore q can be approximated as a 2^1023.  we drop the subset of
     # potential x where the first 63 bits are 1, because some of those will be
     # larger than q (but this is a tiny tiny subset of potential x).
     while 1:
         x_bytes = self.transport.rng.read(128)
         x_bytes = chr(ord(x_bytes[0]) & 0x7f) + x_bytes[1:]
         if (x_bytes[:8] != '\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF') and \
                (x_bytes[:8] != '\x00\x00\x00\x00\x00\x00\x00\x00'):
             break
     self.x = util.inflate_long(x_bytes)
示例#10
0
 def _generate_x(self):
     # generate an "x" (1 < x < q), where q is (p-1)/2.
     # p is a 128-byte (1024-bit) number, where the first 64 bits are 1. 
     # therefore q can be approximated as a 2^1023.  we drop the subset of
     # potential x where the first 63 bits are 1, because some of those will be
     # larger than q (but this is a tiny tiny subset of potential x).
     while 1:
         x_bytes = self.transport.rng.read(128)
         x_bytes = chr(ord(x_bytes[0]) & 0x7f) + x_bytes[1:]
         if (x_bytes[:8] != '\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF') and \
                (x_bytes[:8] != '\x00\x00\x00\x00\x00\x00\x00\x00'):
             break
     self.x = util.inflate_long(x_bytes)
示例#11
0
def _generate_prime(bits, rng):
    "primtive attempt at prime generation"
    hbyte_mask = pow(2, bits % 8) - 1
    while True:
        # loop catches the case where we increment n into a higher bit-range
        x = rng.read((bits+7) // 8)
        if hbyte_mask > 0:
            x = chr(ord(x[0]) & hbyte_mask) + x[1:]
        n = util.inflate_long(x, 1)
        n |= 1
        n |= (1 << (bits - 1))
        while not number.isPrime(n):
            n += 2
        if util.bit_length(n) == bits:
            break
    return n
示例#12
0
 def _generate_x(self):
     # generate an "x" (1 < x < (p-1)/2).
     q = (self.p - 1) // 2
     qnorm = util.deflate_long(q, 0)
     qhbyte = ord(qnorm[0])
     bytes = len(qnorm)
     qmask = 0xff
     while not (qhbyte & 0x80):
         qhbyte <<= 1
         qmask >>= 1
     while True:
         x_bytes = self.transport.rng.read(bytes)
         x_bytes = chr(ord(x_bytes[0]) & qmask) + x_bytes[1:]
         x = util.inflate_long(x_bytes, 1)
         if (x > 1) and (x < q):
             break
     self.x = x
示例#13
0
 def _generate_x(self):
     # generate an "x" (1 < x < (p-1)/2).
     q = (self.p - 1) // 2
     qnorm = util.deflate_long(q, 0)
     qhbyte = ord(qnorm[0])
     bytes = len(qnorm)
     qmask = 0xff
     while not (qhbyte & 0x80):
         qhbyte <<= 1
         qmask >>= 1
     while True:
         x_bytes = self.transport.rng.read(bytes)
         x_bytes = chr(ord(x_bytes[0]) & qmask) + x_bytes[1:]
         x = util.inflate_long(x_bytes, 1)
         if (x > 1) and (x < q):
             break
     self.x = x
示例#14
0
def _roll_random(rng, n):
    "returns a random # from 0 to N-1"
    bits = util.bit_length(n-1)
    bytes = (bits + 7) // 8
    hbyte_mask = pow(2, bits % 8) - 1

    # so here's the plan:
    # we fetch as many random bits as we'd need to fit N-1, and if the
    # generated number is >= N, we try again.  in the worst case (N-1 is a
    # power of 2), we have slightly better than 50% odds of getting one that
    # fits, so i can't guarantee that this loop will ever finish, but the odds
    # of it looping forever should be infinitesimal.
    while True:
        x = rng.read(bytes)
        if hbyte_mask > 0:
            x = chr(ord(x[0]) & hbyte_mask) + x[1:]
        num = util.inflate_long(x, 1)
        if num < n:
            break
    return num