Example #1
0
    def verify_ssh_sig(self, data, msg):
        if len(msg.asbytes()) == 40:
            # spies.com bug: signature has no header
            sig = msg.asbytes()
        else:
            kind = msg.get_text()
            if kind != 'ssh-dss':
                return 0
            sig = msg.get_binary()

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

        signature = encode_dss_signature(sigR, sigS)

        key = dsa.DSAPublicNumbers(
            y=self.y,
            parameter_numbers=dsa.DSAParameterNumbers(
                p=self.p,
                q=self.q,
                g=self.g
            )
        ).public_key(backend=default_backend())
        verifier = key.verifier(signature, hashes.SHA1())
        verifier.update(data)
        try:
            verifier.verify()
        except InvalidSignature:
            return False
        else:
            return True
Example #2
0
    def __init__(self, msg=None, data=None, filename=None, password=None,
                 vals=None, file_obj=None, validate_point=True):
        self.verifying_key = None
        self.signing_key = None
        if file_obj is not None:
            self._from_private_key(file_obj, password)
            return
        if filename is not None:
            self._from_private_key_file(filename, password)
            return
        if (msg is None) and (data is not None):
            msg = Message(data)
        if vals is not None:
            self.signing_key, self.verifying_key = vals
        else:
            if msg is None:
                raise SSHException('Key object may not be empty')
            if msg.get_text() != 'ecdsa-sha2-nistp256':
                raise SSHException('Invalid key')
            curvename = msg.get_text()
            if curvename != 'nistp256':
                raise SSHException("Can't handle curve of type %s" % curvename)

            pointinfo = msg.get_binary()
            if pointinfo[0:1] != four_byte:
                raise SSHException('Point compression is being used: %s' %
                                   binascii.hexlify(pointinfo))
            curve = ec.SECP256R1()
            numbers = ec.EllipticCurvePublicNumbers(
                x=inflate_long(pointinfo[1:1 + curve.key_size // 8], always_positive=True),
                y=inflate_long(pointinfo[1 + curve.key_size // 8:], always_positive=True),
                curve=curve
            )
            self.verifying_key = numbers.public_key(backend=default_backend())
        self.size = 256
Example #3
0
 def verify_ssh_sig(self, data, msg):
     if msg.get_text() != 'ssh-rsa':
         return False
     sig = util.inflate_long(msg.get_binary(), 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,))
Example #4
0
    def get_mpint(self):
        """
        Fetch a long int (mpint) from the stream.

        :return: an arbitrary-length integer (`long`).
        """
        return util.inflate_long(self.get_binary())
Example #5
0
    def verify_ssh_sig(self, data, msg):
        if len(msg.asbytes()) == 40:
            # spies.com bug: signature has no header
            sig = msg.asbytes()
        else:
            kind = msg.get_text()
            if kind != 'ssh-dss':
                return 0
            sig = msg.get_binary()

        # 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(sha1(data).digest(), 1)

        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
        return dss.verify(sigM, (sigR, sigS))
Example #6
0
    def verify_ssh_sig(self, data, msg):
        if len(bytes(msg)) == 40:
            # spies.com bug: signature has no header
            sig = bytes(msg)
        else:
            kind = msg.get_string()
            if kind != b'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((self.y, self.g, self.p, self.q))
        return dss.verify(sigM, (sigR, sigS))
Example #7
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())
Example #8
0
File: ber.py Project: OmniDB/OmniDB
 def decode_next(self):
     if self.idx >= len(self.content):
         return None
     ident = byte_ord(self.content[self.idx])
     self.idx += 1
     if (ident & 31) == 31:
         # identifier > 30
         ident = 0
         while self.idx < len(self.content):
             t = byte_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 = byte_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)
         msg = "Unknown ber encoding type {:d} (robey is lazy)"
         raise BERException(msg.format(ident))
Example #9
0
    def get_adaptive_int(self):
        """
        Fetch an int from the stream.

        :return: a 32-bit unsigned `int`.
        """
        byte = self.get_bytes(1)
        if byte == max_byte:
            return util.inflate_long(self.get_binary())
        byte += self.get_bytes(3)
        return struct.unpack('>I', byte)[0]
Example #10
0
 def sign_ssh_data(self, data):
     digest = sha1(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(os.urandom(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 = zero_byte * (20 - len(rstr)) + rstr
     if len(sstr) < 20:
         sstr = zero_byte * (20 - len(sstr)) + sstr
     m.add_string(rstr + sstr)
     return m
Example #11
0
    def get_int(self):
        """
        Fetch an int from the stream.

        @return: a 32-bit unsigned integer.
        @rtype: int
        """
        byte = self.get_bytes(1)
        if byte == max_byte:
            return util.inflate_long(self.get_binary())
        byte += self.get_bytes(3)
        return struct.unpack('>I', byte)[0]
Example #12
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 = os.urandom(128)
         x_bytes = byte_mask(x_bytes[0], 0x7F) + x_bytes[1:]
         if x_bytes[:8] != b7fffffffffffffff and x_bytes[:8] != b0000000000000000:
             break
     self.x = util.inflate_long(x_bytes)
Example #13
0
 def sign_ssh_data(self, rng, data):
     digest = SHA.new(data).digest()
     dss = DSA.construct((self.y, self.g, self.p, self.q, 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(b'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 = b'\x00' * (20 - len(rstr)) + rstr
     if len(sstr) < 20:
         sstr = b'\x00' * (20 - len(sstr)) + sstr
     m.add_string(rstr + sstr)
     return m
Example #14
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)
Example #15
0
File: dsskey.py Project: xiar/idic
 def sign_ssh_data(self, data):
     digest = sha1(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(os.urandom(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 = zero_byte * (20 - len(rstr)) + rstr
     if len(sstr) < 20:
         sstr = zero_byte * (20 - len(sstr)) + sstr
     m.add_string(rstr + sstr)
     return m
Example #16
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 = os.urandom(128)
         x_bytes = byte_mask(x_bytes[0], 0x7f) + x_bytes[1:]
         if (x_bytes[:8] != b7fffffffffffffff and
                 x_bytes[:8] != b0000000000000000):
             break
     self.x = util.inflate_long(x_bytes)
Example #17
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:
         self.transport.randpool.stir()
         x_bytes = self.transport.randpool.get_bytes(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)
Example #18
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 = byte_mask(x_bytes[0], 0x7f) + x_bytes[1:]
         if (x_bytes[:8] != self.b7fffffffffffffff) and \
                (x_bytes[:8] != self.b0000000000000000):
             break
     self.x = util.inflate_long(x_bytes)
Example #19
0
def _generate_prime(bits, randpool):
    "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 = randpool.get_bytes((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:
            return n
Example #20
0
def _generate_prime(bits, randpool):
    "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 = randpool.get_bytes((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:
            return n
Example #21
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 = os.urandom(128)
         x_bytes = byte_mask(x_bytes[0], 0x7f) + x_bytes[1:]
         first = x_bytes[:8]
         if first not in (self.b7fffffffffffffff, self.b0000000000000000):
             break
     self.x = util.inflate_long(x_bytes)
Example #22
0
 def _uint32_cstruct_unpack(self, data, strformat):
     """
     Used to read new OpenSSH private key format.
     Unpacks a c data structure containing a mix of 32-bit uints and
     variable length strings prefixed by 32-bit uint size field,
     according to the specified format. Returns the unpacked vars
     in a tuple.
     Format strings:
       s - denotes a string
       i - denotes a long integer, encoded as a byte string
       u - denotes a 32-bit unsigned integer
       r - the remainder of the input string, returned as a string
     """
     arr = []
     idx = 0
     try:
         for f in strformat:
             if f == "s":
                 # string
                 s_size = struct.unpack(">L", data[idx:idx + 4])[0]
                 idx += 4
                 s = data[idx:idx + s_size]
                 idx += s_size
                 arr.append(s)
             if f == "i":
                 # long integer
                 s_size = struct.unpack(">L", data[idx:idx + 4])[0]
                 idx += 4
                 s = data[idx:idx + s_size]
                 idx += s_size
                 i = util.inflate_long(s, True)
                 arr.append(i)
             elif f == "u":
                 # 32-bit unsigned int
                 u = struct.unpack(">L", data[idx:idx + 4])[0]
                 idx += 4
                 arr.append(u)
             elif f == "r":
                 # remainder as string
                 s = data[idx:]
                 arr.append(s)
                 break
     except Exception as e:
         # PKey-consuming code frequently wants to save-and-skip-over issues
         # with loading keys, and uses SSHException as the (really friggin
         # awful) signal for this. So for now...we do this.
         raise SSHException(str(e))
     return tuple(arr)
Example #23
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 = byte_mask(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
Example #24
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 = byte_mask(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
Example #25
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
Example #26
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 = qnorm[0]
     bytes = len(qnorm)
     qmask = 0xff
     while not (qhbyte & 0x80):
         qhbyte <<= 1
         qmask >>= 1
     while True:
         x_bytes = bytearray(self.transport.rng.read(bytes))
         x_bytes[0] &= qmask
         x = util.inflate_long(x_bytes, 1)
         if (x > 1) and (x < q):
             break
     self.x = x
Example #27
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 = byte_ord(qnorm[0])
     byte_count = len(qnorm)
     qmask = 0xff
     while not (qhbyte & 0x80):
         qhbyte <<= 1
         qmask >>= 1
     while True:
         x_bytes = os.urandom(byte_count)
         x_bytes = byte_mask(x_bytes[0], qmask) + x_bytes[1:]
         x = util.inflate_long(x_bytes, 1)
         if (x > 1) and (x < q):
             break
     self.x = x
Example #28
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 = byte_ord(qnorm[0])
     byte_count = len(qnorm)
     qmask = 0xff
     while not (qhbyte & 0x80):
         qhbyte <<= 1
         qmask >>= 1
     while True:
         x_bytes = os.urandom(byte_count)
         x_bytes = byte_mask(x_bytes[0], qmask) + x_bytes[1:]
         x = util.inflate_long(x_bytes, 1)
         if (x > 1) and (x < q):
             break
     self.x = x
Example #29
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:
         self.transport.randpool.stir()
         x_bytes = self.transport.randpool.get_bytes(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
Example #30
0
def _roll_random(rpool, 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 = rpool.get_bytes(bytes)
        if hbyte_mask > 0:
            x = chr(ord(x[0]) & hbyte_mask) + x[1:]
        num = util.inflate_long(x, 1)
        if num < n:
            return num
Example #31
0
def _roll_random(rpool, 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 = rpool.get_bytes(bytes)
        if hbyte_mask > 0:
            x = chr(ord(x[0]) & hbyte_mask) + x[1:]
        num = util.inflate_long(x, 1)
        if num < n:
            return num