*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
- * Copyright 2005 TRI-D Systems, Inc.
+ * Copyright 2005,2006 TRI-D Systems, Inc.
*/
#include <inttypes.h>
{ "cryptocard-d8-rc", CRYPTOCARD_D8_RC },
{ "cryptocard-h7-rc", CRYPTOCARD_H7_RC },
{ "cryptocard-d7-rc", CRYPTOCARD_D7_RC },
+ { "cryptocard-hp-rc", CRYPTOCARD_HP_RC },
+ { "cryptocard-dp-rc", CRYPTOCARD_DP_RC },
{ "cryptocard-h8-es", CRYPTOCARD_H8_ES },
{ "cryptocard-d8-es", CRYPTOCARD_D8_ES },
{ "cryptocard-h7-es", CRYPTOCARD_H7_ES },
{ "cryptocard-d7-es", CRYPTOCARD_D7_ES },
+ { "cryptocard-hp-es", CRYPTOCARD_HP_ES },
+ { "cryptocard-dp-es", CRYPTOCARD_DP_ES },
{ "cryptocard-h8-rs", CRYPTOCARD_H8_RS },
{ "cryptocard-d8-rs", CRYPTOCARD_D8_RS },
{ "cryptocard-h7-rs", CRYPTOCARD_H7_RS },
{ "cryptocard-d7-rs", CRYPTOCARD_D7_RS },
+ { "cryptocard-hp-rs", CRYPTOCARD_HP_RS },
+ { "cryptocard-dp-rs", CRYPTOCARD_DP_RS },
{ NULL, 0 } /* end of list */
};
/*
* Convert an ASCII keystring to a keyblock.
- * Returns 0 on success, non-zero otherwise.
+ * Returns keylen on success, -1 otherwise.
*/
static int
cryptocard_keystring2keyblock(const char *keystring,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
- const otp_user_info_t *user_info,
+ const otp_card_info_t *card_info,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
time_t when,
const char *log_prefix)
{
- otp_log(OTP_LOG_ERR, "%s: null state not supported for CRYPTOCard",
- log_prefix);
+ otp_log(OTP_LOG_ERR, "%s: %s: null state not supported for CRYPTOCard",
+ log_prefix, __func__);
return -1;
}
/*
* Return a synchronous challenge.
- * Returns 0 on success, non-zero otherwise.
+ * Returns 0 on success, -1 otherwise.
+ * (-2 rc is for early challenge, N/A for cryptocard.)
*/
static int
-cryptocard_challenge(const otp_user_info_t *user_info,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char csd[OTP_MAX_CSD_LEN + 1],
- char challenge[OTP_MAX_CHALLENGE_LEN + 1],
+cryptocard_challenge(const otp_card_info_t *card_info,
+ otp_user_state_t *user_state,
+ unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
#ifdef __GNUC__
__attribute__ ((unused))
#endif
unsigned char output[8];
int i;
- /* CRYPTOCard sync challenges are always 8 bytes. */
- if (strlen(challenge) != 8)
- return -1;
-
- /* run x99 once on the challenge */
- if (otp_x99_mac(challenge, 8, output, user_info->keyblock, log_prefix))
+ /* run x99 once on the previous challenge */
+ if (otp_x99_mac(challenge, user_state->clen, output, card_info->keyblock,
+ log_prefix))
return -1;
/* convert the mac into the next challenge */
output[i] |= 0x30;
}
(void) memcpy(challenge, output, 8);
- challenge[8] = '\0';
+ user_state->clen = 8;
return 0;
}
* 5. Truncate the response for 7 digit display modes.
*/
static int
-cryptocard_response(otp_user_info_t *user_info,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char csd[OTP_MAX_CSD_LEN + 1],
- const char challenge[OTP_MAX_CHALLENGE_LEN + 1],
- char response[OTP_MAX_RESPONSE_LEN + 1],
+cryptocard_response(otp_card_info_t *card_info,
+ const unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
+ size_t len, char response[OTP_MAX_RESPONSE_LEN + 1],
const char *log_prefix)
{
unsigned char output[8];
- char l_response[17];
const char *conversion;
/* Step 1, 2. */
- if (otp_x99_mac(challenge, strlen(challenge), output,
- user_info->keyblock, log_prefix) !=0)
+ if (otp_x99_mac(challenge, len, output,
+ card_info->keyblock, log_prefix) !=0)
return 1;
/* Setup for step 4. */
- if (user_info->featuremask & OTP_CF_DD)
+ if (card_info->featuremask & OTP_CF_DD)
conversion = otp_cc_dec_conversion;
else
conversion = otp_hex_conversion;
/* Step 3, 4. */
- otp_keyblock2keystring(l_response, output, conversion);
- (void) memcpy(response, l_response, 8);
- response[8] = '\0';
+ (void) otp_keyblock2keystring(response, output, 4, conversion);
/* Step 5. */
- if (user_info->featuremask & OTP_CF_R7)
+ if (card_info->featuremask & OTP_CF_R7)
(void) memmove(&response[3], &response[4], 5);
+ else if (card_info->featuremask & OTP_CF_RP)
+ response[3] = '-';
return 0;
}
* Returns 0 if succesful, -1 otherwise.
*/
static int
-cryptocard_updatecsd(
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const otp_user_info_t *user_info,
- otp_user_state_t *user_state,
+cryptocard_updatecsd(otp_user_state_t *user_state,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
- const char challenge[OTP_MAX_CHALLENGE_LEN + 1],
+ time_t when,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
int twin,
int ewin,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- time_t when,
- int auth_rc,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char *log_prefix)
+ int auth_rc)
{
if (auth_rc == OTP_RC_OK)
user_state->rd[0] = '\0'; /* reset */
}
-/* events can only go forward, so an auth can never be too early */
-static int
-cryptocard_isearly(
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const otp_user_state_t *user_state,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char challenge[OTP_MAX_CHALLENGE_LEN + 1],
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char *log_prefix)
-{
- return 0;
-}
-
-
/*
* Determine if a window position if consecutive relative to a saved
* (rwindow candidate) window position, for rwindow override.
*/
static int
cryptocard_isconsecutive(
- const otp_user_info_t *user_info,
- const otp_user_state_t *user_state,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
- int twin,
- int ewin,
- const char *log_prefix)
+ const otp_card_info_t *card_info,
+ const otp_user_state_t *user_state,
+ int thisewin, const char *log_prefix)
{
- int rcanewin; /* saved rwindow candidate window position */
+ int nextewin;
/* extract the saved rwindow candidate position */
- if (sscanf(user_state->rd, "%" SCNx32, &rcanewin) != 1) {
- otp_log(OTP_LOG_ERR, "%s: %s: invalid rwindow data for [%s]", log_prefix,
- __func__, user_info->username);
+ if (sscanf(user_state->rd, "%" SCNx32, &nextewin) != 1) {
+ otp_log(OTP_LOG_ERR, "%s: %s: invalid rwindow data for [%s]",
+ log_prefix, __func__, card_info->username);
return 0;
}
+ nextewin++;
/* Is this the next passcode? */
- if (ewin == rcanewin + 1)
+ if (thisewin == nextewin)
return 1; /* yes */
else
return 0; /* no */
#ifdef __GNUC__
__attribute__ ((unused))
#endif
- const otp_user_info_t *user_info,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
- const char csd[OTP_MAX_CSD_LEN + 1],
+ const otp_card_info_t *card_info,
#ifdef __GNUC__
__attribute__ ((unused))
#endif
- time_t when)
+ const char csd[OTP_MAX_CSD_LEN + 1])
{
return 0;
}
+/* return human-readable challenge */
+static char *
+cryptocard_printchallenge(char s[OTP_MAX_CHALLENGE_LEN * 2 + 1],
+ const unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
+ size_t len)
+{
+ /* cryptocard challenge is implicitly ASCII */
+ (void) memcpy(s, challenge, len);
+ s[len] = '\0';
+ return s;
+}
+
+
/* cardops instance */
static cardops_t cryptocard_cardops = {
.prefix = "cryptocard",
.challenge = cryptocard_challenge,
.response = cryptocard_response,
.updatecsd = cryptocard_updatecsd,
- .isearly = cryptocard_isearly,
.isconsecutive = cryptocard_isconsecutive,
.maxtwin = cryptocard_maxtwin,
+ .printchallenge = cryptocard_printchallenge,
};