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:
TokenClass
Ocra2TokenClass 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