linotp.tokens.ocra2token.ocra2token module¶
- This file containes the standard token definitions:
OCRA2TokenClass
the OCRA2 Token will use the standard challenge response instead of the dedicated ocra/request and ocra/check_t
The rollout is a 2 step process with the following steps:
call the /admin/init controller with the following parameters
- param type:
must be “ocra2” for an ocra2 token
- param genkey:
must be “1”, if the server should generate the seed otherwise you can use the :param otpkey: with the seed
- param ocrasuite:
your ocra suite of choice e.g. “OCRA-1:HOTP-SHA256-8:C-QA64”
- param sharedsecret:
value must be “1”
- param serial:
optional, if the serial will be defined by external
as reply a set of information is returned, where the relevant part is the in the image data for the softtoken qrscan in the structure
detail/ocraurl/img
<img width=250 src=”data:image/png;base64,iVBO….
which could be embedded in the enrollment application. Other relevant information (as well part in the qr encoded data) is the
“sharedsecret”: “25676ef34bd1873834bbe10c4c4176b0a9689619”
which is the server data part for the pairing process transferd to the qrtan app.
2. complete the rollout The qrtan app will calculate an activation code, that must be transfered back to the server as a set of input data for the second enrollment step by calling the /admin/init controller with the following parameters:
- param type:
must be of the same token type “ocra2”
- param serial:
must be the same as received from the first request
- param genkey:
must be of “1”, which indicates, that the init is not finished
- param activationcode:
“GEZDGNBVGY3TQOJQ01”,
- param ocrasuite:
same ocrasuite as above “OCRA-1:HOTP-SHA256-8:C-QA64”,
- param message:
optional the message, that is displayed in the app, e.g. “Transaktion: Ausrollen eines OCRA2 Tokens”,
As response again an <img > is returned, which is the ‘finishing’ transaction, where the qrtan app will reply only with an otp value
Further challenge request and response processing could then be managed by using the /validate/check_s with
- param serial:
token serial number, as defined above
- param challenge:
the challenge input data as heart of the transaction
or when using /validate/check with
- param user:
the assigned token user / owner
- param passw:
which contains the token pin
- param challenge:
the challenge input data as heart of the transaction
a response to this request will then contain the /detail/ocraurl/img image data and the transaction id, which is the referer to the incomming challenge respones from the qrtan app.
The challenge response then is verified by /validate/check_t and the parameters:
- param transactionid:
the transaction id “440364804594”,
- param pass:
the otp value e.g. “48344099”
But as well the /validate/check controller could be used to verify the transaction by providing in addition the user name.
- class linotp.tokens.ocra2token.ocra2token.Ocra2TokenClass(aToken)¶
Bases:
TokenClassOcra2TokenClass implement an ocra compliant token
- used from Config
- OcraMaxChallenges - number of open challenges per token
if None: 3
Ocra2ChallengeValidityTime timeout definition in seconds OcraDefaultSuite - if none :’OCRA-1:HOTP-SHA256-8:C-QN08’ QrOcraDefaultSuite - if none :’OCRA-1:HOTP-SHA256-8:C-QA64’
algorithm Ocra Token Rollout: tow phases of rollout
- https://linotpserver/admin/init?
type=ocra& genkey=1& sharedsecret=1& user=BENUTZERNAME& session=SESSIONKEY
=>> “serial” : SERIENNUMMER, “sharedsecret” : DATAOBJECT, “app_import” : IMPORTURL - genSharedSecret - vom HSM oder urandom ? - app_import : + linotp://
ocrasuite ->> default aus dem config: (DefaultOcraSuite)
sharedsecret (Länge wie ???)
seriennummer
seriennummer: uuid
token wird angelegt ist aber nicht aktiv!!! (counter == 0)
- https://linotpserver/admin/init?
type=ocra& genkey=1& activationcode=AKTIVIERUNGSCODE& user=BENUTZERNAME& message=MESSAGE& session=SESSIONKEY
=>> “serial” : SERIENNUMMER, “nonce” : DATAOBJECT, “transactionid” : “TRANSAKTIONSID, “app_import” : IMPORTURL
nonce - von HSM oder random ?
pkcs5 - kdf2
es darf zur einer Zeit nur eine QR Token inaktiv (== im Ausrollzustand) sein !!!!! der Token wird über den User gefunden
seed = pdkdf2(nonce + activcode + shared secret)
challenge generiern - von urandom oder HSM
- check_t
counter ist > nach der ersten Transaktion
if counter >= 1: delete sharedsecret löschen
- autosync(ocraSuite, passw, challenge)¶
try to resync a token automaticaly, if a former and the current request failed
- Parameters:
ocraSuite (ocra object) – the ocraSuite of the current Token
passw –
- challenge(data, session='', typ='raw', challenge=None)¶
the challenge method is for creating an transaction / challenge object
- remark: the transaction has a maximum lifetime and a reference to
the OcraSuite token (serial)
- Parameters:
data (string or None) – data, which is the base for the challenge or None
session (string) – session support for ocratokens
- Returns:
challenge response containing the transcation id and the challenge for the ocrasuite
:rtype : tuple of (transId(string), challenge(string))
- checkOtp(passw, counter, window, options=None)¶
checkOtp - standard callback of linotp to verify the token
- Parameters:
passw (string) – the passw / otp, which has to be checked
counter (int) – the start counter
window (int) – the window, in which the token is valid
options (dict) – options contains the transaction id, eg. if check_t checks one transaction this will support assynchreonous otp checks (when check_t is used)
- Returns:
verification counter or -1
- Return type:
int (-1)
- checkResponse4Challenge(user, passw, options=None, challenges=None)¶
verify the response of a previous challenge
- Parameters:
user – the requesting user
passw – the to be checked pass: (otp) & trans_id | (pin+otp)
options – options an additional argument, which could be token specific
challenges – the list of challenges, where each challenge is described as dict
- Returns:
tuple of (boolean and the list matching challenge ids)
- createChallenge(state, options=None)¶
standard API to create an ocra challenge
- classmethod getClassInfo(key=None, ret='all')¶
getClassInfo - returns all or a subtree of the token definition
- Parameters:
key (string) – subsection identifier
ret (user defined) – default return value, if nothing is found
- Returns:
subsection if key exists or user defined
:rtype : s.o.
- classmethod getClassPrefix()¶
- classmethod getClassType()¶
getClassType - return the token type shortname
- Returns:
‘ocra2’
- Return type:
string
- getInfo()¶
getInfo - return the status of the token rollout
- Returns:
info of the ocra token state
- Return type:
dict
- getInitDetail(params, user=None)¶
to complete the token normalisation, the response of the initialiastion should be build by the token specific method, the getInitDetails
- getOcraSuiteSuite()¶
getQROcraSuiteSuite - return the QR Ocra Suite - if none, it will return the default
- Returns:
Ocrasuite of token
- Return type:
string
- getQRImageData(response_detail)¶
- getQROcraSuiteSuite()¶
getQROcraSuiteSuite - return the QR Ocra Suite - if none, it will return the default
- Returns:
QROcrasuite of token
- Return type:
string
- getStatus(transactionId)¶
getStatus - assembles the status of a transaction / challenge in a dict
- { “serial”: SERIENNUMMER1,
“transactionid”: TRANSACTIONID1, “received_tan”: true, “valid_tan”: true, “failcount”: 0
}
- Parameters:
transactionId (string) – the transaction / challenge id
- Returns:
status dict
- Return type:
dict
- get_enrollment_status()¶
return the enrollemnt status
- classmethod get_helper_params_post(param, user=None)¶
hook method which gets called with the parameters given to admin/init and the user that possibly gets created from it. It returns a dictionary which will be added to the helper_params. In contrast to get_helper_params_pre this function will be called _after_ the user object gets created from the parameters
- Params params:
the request parameters supplied to admin/init
- Params user:
the user object created from the request parameters (None if no user was specified in the request)
- Returns:
dictionary with additional helper params
- is_challenge_request(passw, user, options=None)¶
check, if the request would start a challenge
default: if the passw contains only the pin, this request would
trigger a challenge
in this place as well the policy for a token is checked
- Parameters:
passw – password, which might be pin or pin+otp
options – dictionary of additional request parameters
- Retrun:
returns true or false
- is_challenge_response(passw, user, options=None, challenges=None)¶
test for the ocra token, if this is a response to a challenge
normal challenge response brings in a password and there is at least a stored challenge available. But OCRA support as well direct challenges, which bring the challenge data and the otp within the same request.
- Parameters:
passw – password, which might be pin or pin+otp
user – the requesting user
options – dictionary of additional request parameters
- Returns:
returns true or false
- prepare_message(data, transId)¶
prepare the challenge response message
- Parameters:
data –
transId – the transaction/state refenence id
remark: we need the state/transId in the inner scope to support the signing of the whole request including the state/transId
- resync(otp1, otp2, options=None)¶
for the resync to work, we take the last two transactions and their challenges
for each challenge, we search forward the sync window length
- signData(data)¶
sign the received data with the secret key
- Parameters:
data – arbitrary string object
- Returns:
hexlified signature of the data
- statusValidationFail()¶
statusValidationFail - callback to enable a status change,
will be called if the token verification has failed
:return - nothing
- statusValidationSuccess()¶
statusValidationSuccess - callback to enable a status change,
remark: will be called if the token has been succesfull verified
- Returns:
nothing
- update(params, reset_failcount=True)¶
update: add further definition for token from param in case of init
- verify_challenge_is_valid(challenge, session)¶
verify, if a challenge is valid according to the ocrasuite definition of the token
- linotp.tokens.ocra2token.ocra2token.get_qrtan_url(qrtan_policy_name, realms, callback_id=None)¶
Worker to returns the URL for the half automatic mode for the QR TAN token for the given realm
- Parameters:
qrtan_policy_name – either ‘qrtanurl_init’ or ‘qrtanurl’
realms – list of realms or None
callback_id – support of multiple callback definitions
- Returns:
url string
- Remark:
there might be more than one url, if the token belongs to more than one realm. it is tested, if all are the same, otherwise an exception is raised
- linotp.tokens.ocra2token.ocra2token.qrtan_url(realms, callback_id=None)¶
Returns the URL for the half automatic mode for the QR TAN token for the given realm
- Remark:
there might be more than one url, if the token belongs to more than one realm
- Parameters:
realms – list of realms or None
- Returns:
url string
- linotp.tokens.ocra2token.ocra2token.qrtanurl_init(realms, callback_id=None)¶
Returns the URL for the half automatic mode for the QR TAN token for the given realm
- Remark:
there might be more than one url, if the token belongs to more than one realm
- Parameters:
realms – list of realms or None
- Returns:
url string