Esempio n. 1
0
    def __init__(self, field, comp_type, comp_value):
        '''
        :param field: (name of) field that should meet the condition
        :param comp_type: how to compare the values. One of ('>', '<', '>=', '<=', '==', '!=')
        :param comp_value: value to compare the field to

        :example:

            Render the content of the `If` container only if the value
            in the field called "name" is not 'kitty'

            ::

                Template([
                    String('kitty', name='name'),
                    If(Compare('name', '!=', 'kitty'), [
                        String('current name is not kitty')
                    ])
                ])
        '''
        super(Compare, self).__init__(field=field)
        self._comp_type = comp_type
        if comp_type in Compare._comparison_types:
            if comp_type not in ['==', '!='] and isinstance(comp_value, str):
                raise KittyException(
                    'can\'t use comparison type "%s" with comparison value of type str'
                    % comp_type)
            self._comp_fn = Compare._comparison_types[comp_type]
        else:
            raise KittyException('unknown comparison type (%s)' % (comp_type))
        if isinstance(comp_value, six.string_types):
            comp_value = strToBytes(comp_value)
        self._comp_value = comp_value
Esempio n. 2
0
    def __init__(self, field, comp_type, comp_value):
        '''
        :param field: (name of) field that should meet the condition
        :param comp_type: how to compare the values. One of ('>', '<', '>=', '<=', '==', '!=')
        :param comp_value: value to compare the field to

        :example:

            ::

                Template([
                    String(['kitty'], name='name'),
                    If(Compare('name', '!=', 'kitty'), [
                        String('123')
                    ])
                ])
        '''
        super(Compare, self).__init__(field=field)
        self._comp_type = comp_type
        if comp_type in Compare._comparison_types:
            if comp_type not in ['==', '!='] and isinstance(comp_value, str):
                raise KittyException(
                    'can\'t use comparison type "%s" with comparison value of type str'
                    % comp_type)
            self._comp_fn = Compare._comparison_types[comp_type]
        else:
            raise KittyException('unknown comparison type (%s)' % (comp_type))
        self._comp_value = comp_value
Esempio n. 3
0
def url_from_string(url, fuzz_delims=True, fuzzable=True, name=None):
    '''
    Create a URL from string,
    only URLs with supported schemes will result in a lego.
    In the rest of the cases, an exception will be raised.

    :param url: the URL string
    :param fuzz_delims: should fuzz delimiters (default: True)
    :param fuzzable: should the resulted container be fuzzable (default: True)
    :param name: name of the resulted container (default: None)
    '''
    generators = {
        'http': HttpUrl.from_string,
        'https': HttpUrl.from_string,
        'ftp': FtpUrl.from_string,
        'ftps': FtpUrl.from_string,
        'mailto': EmailUrl.from_string,
    }
    parsed = urlparse(url)
    scheme = parsed.scheme
    if not scheme:
        raise KittyException('URL is invalid (no scheme)')
    if scheme in generators:
        generator = generators[scheme]
        return generator(the_url=url,
                         fuzz_delims=fuzz_delims,
                         fuzzable=fuzzable,
                         name=name)
    else:
        raise KittyException('Unknown URL scheme (%s)' % scheme)
Esempio n. 4
0
    def __init__(self, value, num_bytes=1, fuzzable=True, name=None):
        '''
        :type value: str or bytes
        :param value: value to mutate
        :param num_bytes: number of consequtive bytes to flip (invert)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :raises: ``KittyException`` if num_bytes is bigger than the value length
        :raises: ``KittyException`` if num_bytes is not positive
        '''
        kassert.is_of_types(value, (bytes, bytearray, str))
        value = strToBytes(value)
        if len(value) < num_bytes:
            raise KittyException('len(value) <= num_bytes',
                                 (len(value), num_bytes))
        if num_bytes <= 0:
            raise KittyException('num_bytes(%d) <= 0' % (num_bytes))
        super(ByteFlip, self).__init__(value=value,
                                       encoder=ENC_STR_DEFAULT,
                                       fuzzable=fuzzable,
                                       name=name)
        self._data_len = len(value)
        self._num_bytes = num_bytes
        self._num_mutations = self._data_len - (num_bytes - 1)
Esempio n. 5
0
 def _get_ready(self):
     if not self._ready:
         if re.match(Stage._random_pattern, self._strategy):
             self._min_sequence = 1
             self._max_sequence = len(self._templates)
         elif re.match(Stage._all_pattern, self._strategy):
             self._min_sequence = len(self._templates)
             self._max_sequence = len(self._templates)
         elif re.match(Stage._const_pattern, self._strategy):
             self._min_sequence = int(self._strategy)
             self._max_sequence = int(self._strategy)
             if self._max_sequence > len(self._templates):
                 raise KittyException(
                     'bad const strategy %s > template count(%s)' %
                     (self._max_sequence, len(self._templates)))
         elif re.match(Stage._range_pattern, self._strategy):
             ts = self._strategy.split('-')
             self._min_sequence = int(ts[0])
             self._max_sequence = int(ts[1])
             if self._max_sequence < self._min_sequence:
                 raise KittyException('bad range strategy %s, max < min' %
                                      self._strategy)
             if self._max_sequence > len(self._templates):
                 raise KittyException(
                     'bad range strategy %s, max > template count(%s)' %
                     (self._max_sequence, len(self._templates)))
         self._ready = True
Esempio n. 6
0
 def _calc_bounds(self, value, minv, maxv):
     if self._length <= 0:
         raise KittyException('length (%d) <= 0' % (self._length))
     max_possible = 2**self._length - 1
     if self._signed:
         self._min_value = ~(max_possible >> 1)
     else:
         self._min_value = 0
     self._max_value = max_possible + self._min_value
     self._max_min_diff = max_possible
     if maxv is not None:
         if maxv > self._max_value:
             raise KittyException('max_value is too big %d > %d' %
                                  (maxv, self._max_value))
         self._max_value = maxv
     if minv is not None:
         if minv < self._min_value:
             raise KittyException('min_value is too small %d < %d' %
                                  (minv, self._min_value))
         self._min_value = minv
     if self._min_value > self._max_value:
         raise KittyException('min_value (%d) > max_value (%d)' %
                              (self._min_value, self._max_value))
     if (value < self._min_value) or (value > self._max_value):
         raise KittyException(
             'default value (%d) not in range (min=%d, max=%d)' %
             (value, self._min_value, self._max_value))
Esempio n. 7
0
    def _parse(self):
        '''
        Crazy function to check and parse the range list string
        '''
        if not self._ranges_str:
            self._lists = [StartEndList(0, None)]
        else:
            lists = []
            p_single = re.compile(r'(\d+)$')
            p_open_left = re.compile(r'-(\d+)$')
            p_open_right = re.compile(r'(\d+)-$')
            p_closed = re.compile(r'(\d+)-(\d+)$')
            for entry in self._ranges_str.split(','):
                entry = entry.strip()

                # single number
                match = p_single.match(entry)
                if match:
                    num = int(match.groups()[0])
                    lists.append(StartEndList(num, num + 1))
                    continue

                # open left
                match = p_open_left.match(entry)
                if match:
                    end = int(match.groups()[0])
                    lists.append(StartEndList(0, end + 1))
                    continue

                # open right
                match = p_open_right.match(entry)
                if match:
                    start = int(match.groups()[0])
                    self._open_end_start = start
                    lists.append(StartEndList(start, None))
                    continue

                # closed range
                match = p_closed.match(entry)
                if match:
                    start = int(match.groups()[0])
                    end = int(match.groups()[1])
                    lists.append(StartEndList(start, end + 1))
                    continue

                # invalid expression
                raise KittyException('Invalid range found: %s' % entry)

            lists = sorted(lists, key=lambda x: x._start)
            for i in range(len(lists) - 1):
                if lists[i]._end is None:
                    # there is an open end which is not the last in our lists
                    # this is a clear overlap with the last one ...
                    raise KittyException('Overlapping ranges in range list')
                elif lists[i]._end > lists[i + 1]._start:
                    raise KittyException('Overlapping ranges in range list')
            self._lists = lists
Esempio n. 8
0
 def _validate_lengths(self, min_length, max_length):
     kassert.is_int(min_length)
     kassert.is_int(max_length)
     if min_length > max_length:
         raise KittyException('min_length(%d) > max_length(%d)' % (min_length, max_length))
     elif min_length < 0:
         raise KittyException('min_length(%d) < 0' % (min_length))
     elif max_length <= 0:
         raise KittyException('max_length(%d) < 0' % (max_length))
Esempio n. 9
0
    def __init__(self,
                 value,
                 min_length,
                 max_length,
                 unused_bits=0,
                 seed=1235,
                 num_mutations=25,
                 step=None,
                 encoder=ENC_BITS_DEFAULT,
                 fuzzable=True,
                 name=None):
        '''
        :type value: str
        :param value: default value, the last *unsused_bits* will be removed from the value
        :param min_length: minimal length of the field (in bits)
        :param max_length: maximal length of the field (in bits)
        :param unused_bits: how many bits from the value are not used (default: 0)
        :param seed: seed for the random number generator, to allow consistency between runs (default: 1235)
        :param num_mutations: number of mutations to perform (if step is None) (default:25)
        :type step: int
        :param step: step between lengths of each mutation (default: None)
        :type encoder: :class:`~kitty.model.low_level.encoder.BitsEncoder`
        :param encoder: encoder for the field (default: ENC_BITS_DEFAULT)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :examples:

            ::

                RandomBits(value='1234', min_length=0, max_length=75, unused_bits=0, step=15)
                RandomBits(value='1234', min_length=0, max_length=75, unused_bits=3, num_mutations=80)
        '''
        if unused_bits not in range(8):
            raise KittyException('unused bits (%d) is not between 0-7' %
                                 unused_bits)
        value = Bits(bytes=value)
        if unused_bits:
            value = value[:-unused_bits]
        super(RandomBits, self).__init__(value=value,
                                         encoder=encoder,
                                         fuzzable=fuzzable,
                                         name=name)
        self._validate_lengths(min_length, max_length)
        self._min_length = min_length
        self._max_length = max_length
        self._num_mutations = num_mutations
        self._step = step
        self._random = Random()
        self._seed = seed
        self._random.seed(self._seed)
        if self._step:
            if self._step < 0:
                raise KittyException('step (%d) < 0' % (step))
            self._num_mutations = (self._max_length -
                                   self._min_length) / self._step
Esempio n. 10
0
 def _get_ready(self, container):
     if not self._field:
         if self._field_name:
             field = container.resolve_field(self._field_name)
             if not field:
                 raise KittyException('failed to resolve field name %s' %
                                      self._field_name)
             self._field = field
     if not self._field:
         raise KittyException('No field provided to base the condition on')
Esempio n. 11
0
 def _check_session_validity(self):
     current_version = _get_current_version()
     if current_version != self.session_info.kitty_version:
         raise KittyException(
             'kitty version in stored session (%s) != current kitty version (%s)'
             % (current_version, self.session_info.kitty_version))
     model_hash = self.model.hash()
     if model_hash != self.session_info.data_model_hash:
         raise KittyException(
             'data model hash in stored session(%s) != current data model hash (%s)'
             % (model_hash, self.session_info.data_model_hash))
Esempio n. 12
0
    def __init__(self, value, min_length, max_length, seed=1234, num_mutations=25, step=None, encoder=ENC_STR_DEFAULT, fuzzable=True, name=None):
        '''
        :type value: str
        :param value: default value
        :param min_length: minimal length of the field (in bytes)
        :param max_length: maximal length of the field (in bytes)
        :param seed: seed for the random number generator, to allow consistency between runs (default: 1234)
        :param num_mutations: number of mutations to perform (if step is None) (default:25)
        :type step: int
        :param step: step between lengths of each mutation (default: None)
        :type encoder: :class:`~kitty.model.low_level.encoder.StrEncoder`
        :param encoder: encoder for the field (default: ENC_STR_DEFAULT)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :examples:

            ::

                RandomBytes(value='1234', min_length=0, max_length=75, step=15)
                RandomBytes(value='1234', min_length=0, max_length=75, num_mutations=80)
        '''
        super(RandomBytes, self).__init__(value=value, encoder=encoder, fuzzable=fuzzable, name=name)
        self._validate_lengths(min_length, max_length)
        self._min_length = min_length
        self._max_length = max_length
        self._num_mutations = num_mutations
        self._step = step
        self._random = Random()
        self._seed = seed
        self._random.seed(self._seed)
        if self._step:
            if self._step < 0:
                raise KittyException('step (%d) < 0' % (step))
            self._num_mutations = (self._max_length - self._min_length) // self._step
Esempio n. 13
0
    def __init__(self, name, device, baudrate=115200, timeout=0.5,
                 open_at='setup', logger=None, expect_response=False):
        '''
        :param name: name of the target
        :param device: serial device name/path
        :param baudrate: baud rate of the serial channel (default: 115200)
        :param timeout: receive timeout on the channel in seconds (default: 0.5)
        :type open_at: str
        :param open_at:
            at what stage should the port be opened.
            Either 'setup' or 'pre_test' (default: 'setup')
        :param logger: logger for this object (default: None)
        :param expect_response:
            should wait for response from the victim (default: False)

        :examples:

            >>> SerialTarget('SomeTarget', '/dev/ttyUSB0', 57600)
            >>> SerialTarget('ToTarget', '/dev/ttyUSB0', timeout=5)
        '''
        super(SerialTarget, self).__init__(name, logger, expect_response)
        self.device = device
        self.baudrate = baudrate
        self.timeout = timeout
        self.open_at = open_at
        if self.open_at not in ['setup', 'pre_test']:
            raise KittyException('open_at must be either "setup" or "pre_test"')
Esempio n. 14
0
 def __init__(self,
              depends_on,
              encoder=ENC_BITS_DEFAULT,
              fuzzable=True,
              name=None):
     '''
     :param depends_on: (name of) field we depend on
     :type encoder: :class:`~kitty.model.low_level.encoder.BitsEncoder`
     :param encoder: encoder for the field
     :param fuzzable: is container fuzzable
     :param name: (unique) name of the container
     '''
     self._rendered_field = None
     self.dependency_type = Calculated.VALUE_BASED
     super(Calculated, self).__init__(value=self.__class__._default_value_,
                                      encoder=encoder,
                                      fuzzable=fuzzable,
                                      name=name)
     if isinstance(depends_on, str):
         self._field_name = depends_on
         self._field = None
     elif isinstance(depends_on, BaseField):
         self._field_name = None
         self._field = depends_on
     else:
         raise KittyException(
             'depends_on parameter (%s) is neither a string nor a valid field'
             % depends_on)
Esempio n. 15
0
 def __init__(self,
              depends_on,
              length,
              correction=None,
              encoder=ENC_INT_DEFAULT,
              fuzzable=False,
              name=None):
     '''
     :param depends_on: (name of) field we depend on
     :param length: length of the FieldIntProperty field (in bits)
     :type corrention: int or func(int) -> int
     :param correction: correction function, or value for the index
     :type encoder: :class:`~kitty.model.low_level.encoder.BitFieldEncoder`
     :param encoder: encoder for the field (default: ENC_INT_DEFAULT)
     :param fuzzable: is container fuzzable
     :param name: (unique) name of the container (default: None)
     '''
     if correction:
         if not callable(correction):
             if not isinstance(correction, int):
                 raise KittyException(
                     'correction must be int, function or None!')
     self._correction = correction
     bit_field = BitField(value=0, length=length, encoder=encoder)
     super(FieldIntProperty, self).__init__(depends_on=depends_on,
                                            bit_field=bit_field,
                                            calc_func=None,
                                            fuzzable=fuzzable,
                                            name=name)
     self.dependency_type = Calculated.FIELD_PROP_BASED
Esempio n. 16
0
 def render(self, ctx=None):
     '''
     :param ctx: rendering context in which the method was called
     :rtype: `Bits`
     :return: rendered value of the container
     '''
     self._initialize()
     render_count = 1
     if ctx is None:
         ctx = RenderContext()
         if self._need_second_pass:
             render_count = 2
     ctx.push(self)
     if self.is_default():
         self._current_rendered = self._default_rendered
     else:
         if self.offset is None:
             self.offset = 0
         for i in range(render_count):
             offset = self.offset
             rendered = BitArray()
             for field in self._fields:
                 field.set_offset(offset)
                 frendered = field.render(ctx)
                 if not isinstance(frendered, Bits):
                     raise KittyException('the field %s:%s was rendered to type %s, you should probably wrap it with appropriate encoder' % (
                         field.get_name(), type(field), type(frendered)))
                 rendered.append(frendered)
                 offset += len(frendered)
             self.set_current_value(rendered)
     ctx.pop()
     return self._current_rendered
Esempio n. 17
0
    def _handle_options(self, option_line):
        '''
        Handle options from command line, in docopt style.
        This allows passing arguments to the fuzzer from the command line
        without the need to re-write it in each runner.

        :param option_line: string with the command line options to be parsed.
        '''
        if option_line is not None:
            usage = '''
            These are the options to the kitty fuzzer object, not the options to the runner.

            Usage:
                fuzzer [options] [-v ...]

            Options:
                -d --delay <delay>              delay between tests in secodes, float number
                -f --session <session-file>     session file name to use
                -n --no-env-test                don't perform environment test before the fuzzing session
                -r --retest <session-file>      retest failed/error tests from a session file
                -t --test-list <test-list>      a comma delimited test list string of the form "-10,12,15-20,30-"
                -v --verbose                    be more verbose in the log

            Removed options:
                end, start - use --test-list instead
            '''
            options = docopt.docopt(usage, shlex.split(option_line))

            # ranges
            if options['--retest']:
                retest_file = options['--retest']
                try:
                    test_list_str = self._get_test_list_from_session_file(
                        retest_file)
                except Exception as ex:
                    raise KittyException(
                        'Failed to open session file (%s) for retesting: %s' %
                        (retest_file, ex))
            else:
                test_list_str = options['--test-list']
            self._set_test_ranges(None, None, test_list_str)

            # session file
            session_file = options['--session']
            if session_file is not None:
                self.set_session_file(session_file)

            # delay between tests
            delay = options['--delay']
            if delay is not None:
                self.set_delay_between_tests(float(delay))

            # environment test
            skip_env_test = options['--no-env-test']
            if skip_env_test:
                self.set_skip_env_test(True)

            # verbosity
            verbosity = options['--verbose']
            self.set_verbosity(verbosity)
Esempio n. 18
0
 def __init__(self,
              field_count,
              fields=[],
              delim=None,
              encoder=ENC_BITS_DEFAULT,
              fuzzable=True,
              name=None):
     '''
     :param field_count: how many fields to omit in each mutation
     :type fields: field or iterable of fields
     :param fields: enclosed field(s) (default: [])
     :type delim: field
     :param delim: delimiter between elements in the list (default: None)
     :type encoder: BitsEncoder
     :param encoder: encoder for the container (default: ENC_BITS_DEFAULT)
     :param fuzzable: is container fuzzable (default: True)
     :param name: (unique) name of the container (default: None)
     '''
     if field_count < 1:
         raise KittyException('field_count (%s) < 1' % (field_count))
     super(FieldRangeMutator, self).__init__(fields=fields,
                                             encoder=encoder,
                                             fuzzable=fuzzable,
                                             name=name)
     self._field_count = field_count
     self._orig_fields = []
     self._delim = delim
Esempio n. 19
0
    def encode(self, value, length, signed):
        '''
        :param value: value to encode
        :param length: length of value in bits
        :param signed: is value signed
        '''
        if signed:
            raise KittyException('Signed MultiBytes not supported yet, sorry')

        # split to septets
        if value:
            bytes_arr = []
            while value:
                bytes_arr.append((value & 0x7f) | 0x80)
                value >>= 7
        else:
            bytes_arr = [0]

        # reverse if big endian endian
        if self._mode == 'be':
            bytes_arr.reverse()

        # remove msb from last byte
        bytes_arr[-1] = bytes_arr[-1] & 0x7f

        multi_bytes = ''.join(chr(x) for x in bytes_arr)
        return Bits(bytes=multi_bytes)
Esempio n. 20
0
    def copy(self):
        '''
        We might want to change it in the future, but for now...

        :raises: :class:`~kitty.core.KittyException`, as it should not be copied
        '''
        raise KittyException('Template should NOT be copied')
Esempio n. 21
0
 def pre_test(self, test_num=int) -> None:
     """
     This is only checks whether the target is available or not.
     :param test_num: The number of the test case.
     """
     super(ProtobufTarget, self).pre_test(test_num)
     retry_count = 0
     while self.socket is None and retry_count < self.max_retries:
         sock = self._get_socket()
         if self.timeout is not None:
             sock.settimeout(self.timeout)
         try:
             retry_count += 1
             sock.connect((self.host, self.port))
             self.socket = sock
         except Exception:
             sock.close()
             self.logger.error(
                 f"PBTARGET - TCP Error: {traceback.format_exc()}")
             self.logger.error(
                 f"PBTARGET - TCP Failed to connect to target server, retrying..."
             )
             time.sleep(1)
     if self.socket is None:
         raise (KittyException(
             'PBTARGET - TCPTarget: (pre_test) cannot connect to server (retries = %d'
             % retry_count))
Esempio n. 22
0
 def __init__(self,
              value,
              encoder=ENC_BITS_DEFAULT,
              fuzzable=True,
              name=None):
     '''
     :param value: default value
     :type encoder: :class:`~kitty.model.low_level.encoder.BaseEncoder`
     :param encoder: encoder for the field
     :param fuzzable: is field fuzzable (default: True)
     :param name: name of the object (default: None)
     '''
     if name and '/' in name:
         raise KittyException('Name (%s) includes invalid chars /' % (name))
     super(BaseField, self).__init__(name,
                                     logger=logging.getLogger('DataModel'))
     kassert.is_of_types(encoder, self.__class__._encoder_type_)
     self._encoder = encoder
     self._num_mutations = 0
     self._fuzzable = fuzzable
     self._default_value = value
     self._default_rendered = self._encode_value(self._default_value)
     self._current_value = value
     self._current_rendered = self._default_rendered
     self._current_index = -1
     self.enclosing = None
     self._initialized = False
     self._hash = None
     self._need_second_pass = False
     self.offset = None
     self._controlled = False
Esempio n. 23
0
    def __init__(self,
                 field_count,
                 fields=[],
                 encoder=ENC_BITS_DEFAULT,
                 fuzzable=True,
                 name=None):
        '''
        :param field_count: how many fields to omit in each mutation
        :type fields: field or iterable of fields
        :param fields: enclosed field(s) (default: [])
        :type encoder: BitsEncoder
        :param encoder: encoder for the container (default: ENC_BITS_DEFAULT)
        :param fuzzable: is container fuzzable (default: True)
        :param name: (unique) name of the container (default: None)

        :example:

            ::

                RotateMutator(field_count=3, fields=[
                    Static('A'),
                    Static('B'),
                    Static('C'),
                    Static('D'),
                ])

            will result in: BCAD, CABD, ACDB, ADBC
        '''
        if field_count < 2:
            raise KittyException('field_count (%s) < 2' % (field_count))
        super(RotateMutator, self).__init__(field_count=field_count,
                                            fields=fields,
                                            encoder=encoder,
                                            fuzzable=fuzzable,
                                            name=name)
Esempio n. 24
0
def not_none(obj):
    '''
    :param obj: object to assert
    :raise: an exception if obj is not None
    '''
    if obj is None:
        raise KittyException('object is None')
Esempio n. 25
0
 def _validate_strategy(self, strategy):
     valid = False
     if re.match(Stage._all_pattern, strategy):
         valid = True
     elif re.match(Stage._random_pattern, strategy):
         valid = True
     elif re.match(Stage._const_pattern, strategy):
         valid = True
     elif re.match(Stage._range_pattern, strategy):
         ts = strategy.split('-')
         min_sequence = int(ts[0])
         max_sequence = int(ts[1])
         if max_sequence < min_sequence:
             raise KittyException('bad range strategy %s, max < min' % strategy)
         valid = True
     if not valid:
         raise KittyException('strategy %s is not valid' % strategy)
Esempio n. 26
0
def is_in(obj, it):
    '''
    :param obj: object to assert
    :param it: iterable of elements we assert obj is in
    :raise: an exception if obj is in an iterable
    '''
    if obj not in it:
        raise KittyException('(%s) is not in %s' % (obj, it))
Esempio n. 27
0
 def get_field_by_name(self, name):
     '''
     :param name: name of field to get
     :raises: :class:`~kitty.core.KittyException` if no direct subfield with this name
     '''
     raise KittyException(
         'Basic field (%s) does not contain any fields inside (looked for "%s")'
         % (self, name))
Esempio n. 28
0
 def _check_args(self):
     '''
     This is a massive check. argh...
     '''
     if self.key:
         if len(self.key) not in self._key_sizes_:
             raise KittyException('provided key size (%d) not in %s' % (len(self.key), self._key_sizes_))
         if self.key_provider:
             raise KittyException('You should not provide both key and key_provider.')
     elif self.key_provider:
         if not callable(self.key_provider):
             raise KittyException('key_provider must be callable')
         if not self.key_size:
             if self._default_key_size_:
                 self.key_size = self._default_key_size_
             else:
                 raise KittyException('key_size should be specified when using key_provider')
         if self.key_size not in self._key_sizes_:
             raise KittyException('key size (%d) not a valid one (use %s)' % (self.key_size, self._key_sizes_))
     else:
         raise KittyException('You need to provide either key or key_provider')
     if not self.iv:
         self.iv = '\x00' * self._iv_size_
     if len(self.iv) != self._iv_size_:
         raise KittyException('Invalid iv size: %#x. Expected: %#x')
     if not self.padder:
         self.padder = self._zero_padder
     if self.mode is None:
         self.mode = self._default_mode_
Esempio n. 29
0
def is_of_types(obj, the_types):
    '''
    :param obj: object to assert
    :param the_types: iterable of types, or a signle type
    :raise: an exception if obj is not an instance of types
    '''
    if not isinstance(obj, the_types):
        raise KittyException('object type (%s) is not one of (%s)' %
                             (type(obj), the_types))
Esempio n. 30
0
 def encode(self, value):
     '''
     :param value: value to encode
     '''
     kassert.is_of_types(value, Bits)
     if len(value) % 8 != 0:
         raise KittyException(
             'this encoder cannot encode bits that are not byte aligned')
     return self._encoder.encode(value.bytes)