This file is indexed.

/usr/share/pyshared/pyhsm/util.py is in python-pyhsm 1.0.4f-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
"""
collection of utility functions
"""

# Copyright (c) 2011 Yubico AB
# See the file COPYING for licence statement.

import struct

__all__ = [
    # constants
    # functions
    'hexdump',
    'group',
    'key_handle_to_int',
    # classes
]

import pyhsm.exception

def hexdump(src, length=8):
    """ Produce a string hexdump of src, for debug output."""
    if not src:
        return str(src)
    src = input_validate_str(src, 'src')
    offset = 0
    result = ''
    for this in group(src, length):
        hex_s = ' '.join(["%02x" % ord(x) for x in this])
        result += "%04X   %s\n" % (offset, hex_s)
        offset += length
    return result

def group(data, num):
    """ Split data into chunks of num chars each """
    return [data[i:i+num] for i in xrange(0, len(data), num)]

def key_handle_to_int(this):
    """
    Turn "123" into 123 and "KSM1" into 827151179
    (0x314d534b, 'K' = 0x4b, S = '0x53', M = 0x4d).

    YHSM is little endian, so this makes the bytes KSM1 appear
    in the most human readable form in packet traces.
    """
    try:
        num = int(this)
        return num
    except ValueError:
        if this[:2] == "0x":
            return int(this, 16)
        if (len(this) == 4):
            num = struct.unpack('<I', this)[0]
            return num
    raise pyhsm.exception.YHSM_Error("Could not parse key_handle '%s'" % (this))

def input_validate_str(string, name, max_len=None, exact_len=None):
    """ Input validation for strings. """
    if type(string) is not str:
        raise pyhsm.exception.YHSM_WrongInputType(name, str, type(string))
    if max_len != None and len(string) > max_len:
        raise pyhsm.exception.YHSM_InputTooLong(name, max_len, len(string))
    if exact_len != None and len(string) != exact_len:
        raise pyhsm.exception.YHSM_WrongInputSize(name, exact_len, len(string))
    return string

def input_validate_int(value, name, max_value=None):
    """ Input validation for integers. """
    if type(value) is not int:
        raise pyhsm.exception.YHSM_WrongInputType(name, int, type(value))
    if max_value != None and value > max_value:
        raise pyhsm.exception.YHSM_WrongInputSize(name, max_value, value)
    return value

def input_validate_nonce(nonce, name='nonce', pad = False):
    """ Input validation for nonces. """
    if type(nonce) is not str:
        raise pyhsm.exception.YHSM_WrongInputType( \
            name, str, type(nonce))
    if len(nonce) > pyhsm.defines.YSM_AEAD_NONCE_SIZE:
        raise pyhsm.exception.YHSM_InputTooLong(
            name, pyhsm.defines.YSM_AEAD_NONCE_SIZE, len(nonce))
    if pad:
        return nonce.ljust(pyhsm.defines.YSM_AEAD_NONCE_SIZE, chr(0x0))
    else:
        return nonce

def input_validate_key_handle(key_handle, name='key_handle'):
    """ Input validation for key_handles. """
    if type(key_handle) is not int:
        try:
            return key_handle_to_int(key_handle)
        except pyhsm.exception.YHSM_Error:
            raise pyhsm.exception.YHSM_WrongInputType(name, int, type(key_handle))
    return key_handle

def input_validate_yubikey_secret(data, name='data'):
    """ Input validation for YHSM_YubiKeySecret or string. """
    if isinstance(data, pyhsm.aead_cmd.YHSM_YubiKeySecret):
        data = data.pack()
    return input_validate_str(data, name)

def input_validate_aead(aead, name='aead', expected_len=None, max_aead_len = pyhsm.defines.YSM_AEAD_MAX_SIZE):
    """ Input validation for YHSM_GeneratedAEAD or string. """
    if isinstance(aead, pyhsm.aead_cmd.YHSM_GeneratedAEAD):
        aead = aead.data
    if expected_len != None:
        return input_validate_str(aead, name, exact_len = expected_len)
    else:
        return input_validate_str(aead, name, max_len=max_aead_len)



def validate_cmd_response_int(name, got, expected):
    """
    Check that some value returned in the response to a command matches what
    we put in the request (the command).
    """
    if got != expected:
        raise(pyhsm.exception.YHSM_Error("Bad %s in response (got %i, expected %i)" \
                                             % (name, got, expected)))
    return got


def validate_cmd_response_hex(name, got, expected):
    """
    Check that some value returned in the response to a command matches what
    we put in the request (the command).
    """
    if got != expected:
        raise(pyhsm.exception.YHSM_Error("Bad %s in response (got 0x%x, expected 0x%x)" \
                                             % (name, got, expected)))
    return got


def validate_cmd_response_str(name, got, expected, hex_encode=True):
    """
    Check that some value returned in the response to a command matches what
    we put in the request (the command).
    """
    if got != expected:
        if hex_encode:
            got_s = got.encode('hex')
            exp_s = expected.encode('hex')
        else:
            got_s = got
            exp_s = expected
        raise(pyhsm.exception.YHSM_Error("Bad %s in response (got %s, expected %s)" \
                                             % (name, got_s, exp_s)))
    return got

def validate_cmd_response_nonce(got, used):
    """
    Check that the returned nonce matches nonce used in request.

    A request nonce of 000000000000 means the HSM should generate a nonce internally though,
    so if 'used' is all zeros we actually check that 'got' does NOT match 'used'.
    """
    if used == '000000000000'.decode('hex'):
        if got == used:
            raise(pyhsm.exception.YHSM_Error("Bad nonce in response (got %s, expected HSM generated nonce)" \
                                                 % (got.encode('hex'))))
        return got
    return validate_cmd_response_str('nonce', got, used)