The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
decrypt.c
Go to the documentation of this file.
1/**
2 * $Id: 3fd970ccc54d884a5eba35dd6c1ef33eed663d40 $
3 * @file decrypt.c
4 * @brief Authentication for yubikey OTP tokens using the yubikey library.
5 *
6 * @author Arran Cudbard-Bell (a.cudbardb@networkradius.com)
7 * @copyright 2013 The FreeRADIUS server project
8 * @copyright 2013 Network RADIUS (legal@networkradius.com)
9 */
10#include "rlm_yubikey.h"
11
12#ifdef HAVE_YUBIKEY
13
14/** Decrypt a Yubikey OTP AES block
15 *
16 * @param[out] p_result The result of attempt to decrypt the token.
17 * @param[in] mctx call data.
18 * @param[in] request The current request.
19 * @param[in] passcode string to decrypt.
20 */
21unlang_action_t rlm_yubikey_decrypt(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
22{
23 rlm_yubikey_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t);
24 uint32_t counter, timestamp;
25 yubikey_token_st token;
26
27 fr_pair_t *key, *vp;
28
29 key = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_yubikey_key);
30 if (!key) {
31 REDEBUG("Yubikey-Key attribute not found in control list, can't decrypt OTP data");
33 }
34
35 if (key->vp_length != YUBIKEY_KEY_SIZE) {
36 REDEBUG("Yubikey-Key length incorrect, expected %u got %zu", YUBIKEY_KEY_SIZE, key->vp_length);
38 }
39
40 yubikey_parse((uint8_t const *) passcode + inst->id_len, key->vp_octets, &token);
41
42 /*
43 * Apparently this just uses byte offsets...
44 */
45 if (!yubikey_crc_ok_p((uint8_t *) &token)) {
46 REDEBUG("Decrypting OTP token data failed, rejecting");
48 }
49
50 RDEBUG2("Token data decrypted successfully");
51
52 counter = (yubikey_counter(token.ctr) << 8) | token.use;
53 timestamp = (token.tstph << 16) | token.tstpl;
54
55 RDEBUG2("Private ID : %pH", fr_box_octets(token.uid, YUBIKEY_UID_SIZE));
56 RDEBUG2("Session counter : %u", counter);
57
58 RDEBUG2("Token timestamp : %u", timestamp);
59
60 RDEBUG2("Random data : %u", token.rnd);
61 RDEBUG2("CRC data : 0x%x", token.crc);
62
63 /*
64 * Private ID used for validation purposes
65 */
67 fr_pair_value_memdup(vp, token.uid, YUBIKEY_UID_SIZE, true);
68
69 /*
70 * Token timestamp
71 */
73 vp->vp_uint32 = timestamp;
74
75 /*
76 * Token random
77 */
79 vp->vp_uint32 = token.rnd;
80
81 /*
82 * Combine the two counter fields together so we can do
83 * replay attack checks.
84 */
86 vp->vp_uint32 = counter;
87
88 /*
89 * Now we check for replay attacks
90 */
91 vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_yubikey_counter);
92 if (!vp) {
93 RWDEBUG("Yubikey-Counter not found in control list, skipping replay attack checks");
95 }
96
97 if (counter <= vp->vp_uint32) {
98 REDEBUG("Replay attack detected! Counter value %u, is lt or eq to last known counter value %u",
99 counter, vp->vp_uint32);
101 }
102
104}
105#endif
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define MEM(x)
Definition debug.h:36
#define RWDEBUG(fmt,...)
Definition log.h:361
unsigned int uint32_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition pair.c:2981
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition pair.c:770
#define pair_update_request(_attr, _da)
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define RETURN_MODULE_REJECT
Definition rcode.h:55
#define RETURN_MODULE_INVALID
Definition rcode.h:59
#define RETURN_MODULE_OK
Definition rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
fr_dict_attr_t const * attr_yubikey_random
Definition rlm_yubikey.c:68
fr_dict_attr_t const * attr_yubikey_counter
Definition rlm_yubikey.c:66
fr_dict_attr_t const * attr_yubikey_key
Definition rlm_yubikey.c:63
fr_dict_attr_t const * attr_yubikey_timestamp
Definition rlm_yubikey.c:67
fr_dict_attr_t const * attr_yubikey_private_id
Definition rlm_yubikey.c:65
unlang_action_t rlm_yubikey_decrypt(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
void * data
Module's instance data.
Definition module.h:271
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define vp_uint32
Definition pair.h:123
#define fr_box_octets(_val, _len)
Definition value.h:288