linotp.lib.security.pkcs11 module¶
This Security module (hsm) is used to access hardware security modules via PKCS11 for encrypting and decrypting the data
linotp.ini: linotpActiveSecurityModule = lunasa linotpSecurity.lunasa.module = linotp.lib.security.pkcs11.Pkcs11SecurityModule linotpSecurity.lunasa.library = libCryptoki2_64.so linotpSecurity.lunasa.tokenHandle =21 linotpSecurity.lunasa.valueHandle =22 linotpSecurity.lunasa.configHandle =23 linotpSecurity.lunasa.defaultHandle =22 linotpSecurity.lunasa.configLabel = config linotpSecurity.lunasa.tokenLabel = token linotpSecurity.lunasa.valueLabel = value linotpSecurity.lunasa.password = 6SNq-L9WL-SSW4-NGNL linotpSecurity.lunasa.slotid = 1 linotpActiveSecurityModule = lunasa
- class linotp.lib.security.pkcs11.CK_ATTRIBUTE¶
Bases:
Structure
- pValue¶
Structure/Union member
- type¶
Structure/Union member
- ulValueLen¶
Structure/Union member
- class linotp.lib.security.pkcs11.CK_MECHANISM¶
Bases:
Structure
- mechanism¶
Structure/Union member
- pParameter¶
Structure/Union member
- usParameterLen¶
Structure/Union member
- class linotp.lib.security.pkcs11.CK_TOKEN_INFO¶
Bases:
Structure
- firmwareVersion¶
Structure/Union member
- flags¶
Structure/Union member
- hardwareVersion¶
Structure/Union member
- label¶
Structure/Union member
- manufacturerID¶
Structure/Union member
- model¶
Structure/Union member
- serialNumber¶
Structure/Union member
- ulFreePrivateMemory¶
Structure/Union member
- ulFreePublicMemory¶
Structure/Union member
- ulMaxPinLen¶
Structure/Union member
- ulMaxRwSessionCount¶
Structure/Union member
- ulMaxSessionCount¶
Structure/Union member
- ulMinPinLen¶
Structure/Union member
- ulRwSessionCount¶
Structure/Union member
- ulSessionCount¶
Structure/Union member
- ulTotalPrivateMemory¶
Structure/Union member
- ulTotalPublicMemory¶
Structure/Union member
- utcTime¶
Structure/Union member
- class linotp.lib.security.pkcs11.CK_VERSION¶
Bases:
Structure
- major¶
Structure/Union member
- minor¶
Structure/Union member
- class linotp.lib.security.pkcs11.Pkcs11SecurityModule(config=None, add_conf=None)¶
Bases:
DefaultSecurityModule
Class that handles all AES stuff
- createAES(label: bytes, ks: int = 32) c_ulong ¶
Creates a new AES key with the given label and the given length
returns the handle
- decrypt(value: bytes, iv: bytes, id: int = 0) bytes ¶
decrypts the given data, using the IV and the key specified by the handle lookup id
- Parameters
data – the encrypted input data
iv – the initialisation vector
id – id in handle dict - possible id’s are: 0,1,2
- Returns
the decrypted (unpadded) data
- decryptPassword(cryptPass: str) bytes ¶
dedicated security module methods: decryptPassword which used one slot id to decryt a string
- Parameters
cryptPassword (byte string) – the crypted password - leading iv, seperated by the ‘:’
- Returns
decrypted data
- Return type
byte string
- decryptPin(cryptPin: str) bytes ¶
dedicated security module methods: decryptPin which used one slot id to decryt a string
- Parameters
cryptPin (byte string) – the crypted pin - - leading iv, seperated by the ‘:’
- Returns
decrypted data
- Return type
byte string
- encrypt(data: bytes, iv: bytes, id: int = 0) bytes ¶
encrypts the given input data
AES CBC works with a blocksize of 16 byte. Thus data must be a multiple of 16 bytes. This is as well required for the IV.
Note: AES_ECB does not require an IV
- Parameters
data – the to-be-encrypted data
iv – the initialisation vector
id – id in handle dict - possible id’s are: 0,1,2
- Returns
the encrypted byte string
- encryptPassword(password: bytes) str ¶
dedicated security module methods: encryptPassword which used one slot id to encrypt a string
- Parameters
password (byte string) – the to be encrypted password
- Returns
encrypted data - leading iv, seperated by the ‘:’
- Return type
byte string
- encryptPin(pin: bytes, iv: Optional[bytes] = None) str ¶
dedicated security module methods: encryptPin which used one slot id to encrypt a string
- Parameters
pin (byte string) – the to be encrypted pin
iv (buffer (20 bytes random)) – initialisation vector (optional)
- Returns
encrypted data - leading iv, seperated by the ‘:’
- Return type
byte string
- find_aes_keys(label='testAES', wanted=1)¶
Find and AES key with the given label
The number of keys to be found is restricted by “wanted” finding aes keys is done by setting some search attributes when searching for objects. the search attributes which describe an aes key are:
type, class, public accessible, belonging to the current token, usable for encryption / decryption
- Parameters
label – the label of the aes key
wanted – number of maximum returned key
- Returns
if wanted == 1 return 0 or the last in list else return list of aes keys
- gettokeninfo(slotid=0)¶
This returns a dictionary with the token info
- initpkcs11()¶
Initialize the PKCS11 library
- isReady()¶
provides the status, if the security module is fully initializes this is required especially for the runtime confi like set password ++
- Returns
status, if the module is fully operational
- Return type
boolean
- login(password=None, slotid=0)¶
Open a session on the first token
After this, we got a self.hSession
- logout()¶
closes the existing session
- number_or_null = {'anyOf': [{'type': 'number'}, {'type': 'null'}]}¶
- pad(unpadded_str, block=16)¶
PKCS7 padding pads the missing bytes with the value of the number of the bytes. If 4 bytes are missing, this missing bytes are filled with
- Parameters
unpadded_str (bytes) – The byte string to pad
block (int) – Block size
- Returns
padded byte string
- Return type
bytes
- populate_handles()¶
In a HA Group of LunaSAs the handle do not exist. They first need to be populated
The Label overwrites the handles!
- random(l: int = 32) bytes ¶
create a random value and return it l specifies the length of the random data to be created.
- schema = {'properties': {'configHandle': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'configLabel': {'type': 'string'}, 'defaultHandle': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'defaultLabel': {'type': 'string'}, 'library': {'type': 'string'}, 'module': {'type': 'string'}, 'password': {'type': 'string'}, 'poolsize': {'type': 'number'}, 'slotid': {'type': 'number'}, 'tokenHandle': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'tokenLabel': {'type': 'string'}, 'valueHandle': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'valueLabel': {'type': 'string'}}, 'required': ['module', 'library', 'password', 'slotid', 'defaultLabel'], 'type': 'object'}¶
- setup_module(params)¶
used to set the password, if the password is not contained in the config file
- unpad(padded_byte_str: bytes, block_size: int = 16) bytes ¶
PKCS7 padding pads the missing bytes with the value of the number of the bytes. If 4 bytes are missing, this missing bytes are filled with
unpad removes and checks the PKCS #7 padding by verifying that the padding byte string only contains the pad chars
- Parameters
padded_byte_str – The binary string to unpad
block_size – Block size
- Raises
ValueError – If padded_byte_str is not correctly padded a ValueError can be raised. This depends on the ‘pkcs11.accept_invalid_padding’ LinOTP config option. If set to False (default) ValueError is raised. The reason why the data is sometimes incorrectly padded is because the pad() method delivered with LinOTP version < 2.7.1 didn’t pad correctly when the data-length was a multiple of the block-length. Beware that in some cases (statistically about 0.4% of data-chunks whose length is a multiple of the block length) the incorrect padding can not be detected and incomplete data is returned. One example for this last case is when the data ends with the byte 0x01. This is recognized as legitimate padding and is removed before returning the data, thus removing a legitimate byte from the data and making it unusable. If you didn’t upgrade from a LinOTP version before 2.7.1 (or don’t use a PKCS#11 HSM) you will not be affected by this in any way. ValueError will of course also be raised if you data became corrupt for some other reason (e.g. disk failure) and can not be unpadded. In this case you should NOT set ‘pkcs11.accept_invalid_padding’ to True because your data will be unusable anyway.
- Returns
unpadded string or sometimes padded string when ‘pkcs11.accept_invalid_padding’ is set to True. See above.
- Return type
str
- linotp.lib.security.pkcs11.main()¶
This module can be called to create an AES key.
Parameters are:
- -p / –password= The Passwort of the partition. Can be ommitted.
Then you are asked
-s / –slot= The Slot number (default 0) -n / –name= The name of the AES key. -f / –find= Find the AES key -h / –help -e / –encrypt= Encrypt this data (also need slot and handle) -l / –label= Specify the label of the object for encryption
- example:
- create a key:
pkcs11 -s 1335299873-p 1234-n dummy
- find aes key:
pkcs11 -s 1335299873-p 1234-f dummy
- encryption:
pkcs11 -s 1335299873-p 1234-l dummy -e ‘this is a test’
- linotp.lib.security.pkcs11.output(loglevel, text)¶
- linotp.lib.security.pkcs11.pkcs11error(rv)¶