\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /lib/python2.7/site-packages/yubico/

Viewing File: yubikey_frame.py

"""
module for creating frames of data that can be sent to a YubiKey
"""
# Copyright (c) 2010, Yubico AB
# See the file COPYING for licence statement.

__all__ = [
    # constants
    # functions
    # classes
    'YubiKeyFrame',
]

import struct

import yubico_util
import yubikey_defs
import yubico_exception
import yubikey_config
from yubico import __version__

class YubiKeyFrame:
    """
    Class containing an YKFRAME (as defined in ykdef.h).

    A frame is basically 64 bytes of data. When this is to be sent
    to a YubiKey, it is put inside 10 USB HID feature reports. Each
    feature report is 7 bytes of data plus 1 byte of sequencing and
    flags.
    """

    def __init__(self, command, payload=''):
        if payload is '':
            payload = '\x00' * 64
        if len(payload) != 64:
            raise yubico_exception.InputError('payload must be empty or 64 bytes')
        self.payload = payload
        self.command = command
        self.crc = yubico_util.crc16(payload)

    def __repr__(self):
        return '<%s.%s instance at %s: %s>' % (
            self.__class__.__module__,
            self.__class__.__name__,
            hex(id(self)),
            self.command
            )

    def to_string(self):
        """
        Return the frame as a 70 byte string.
        """
        # From ykdef.h :
        #
        # // Frame structure
	# #define SLOT_DATA_SIZE  64
        # typedef struct {
        #     unsigned char payload[SLOT_DATA_SIZE];
        #     unsigned char slot;
        #     unsigned short crc;
        #     unsigned char filler[3];
        # } YKFRAME;
        filler = ''
        return struct.pack('<64sBH3s',
                           self.payload, self.command, self.crc, filler)

    def to_feature_reports(self, debug=False):
        """
        Return the frame as an array of 8-byte parts, ready to be sent to a YubiKey.
        """
        rest = self.to_string()
        seq = 0
        out = []
        # When sending a frame to the YubiKey, we can (should) remove any
        # 7-byte serie that only consists of '\x00', besides the first
        # and last serie.
        while rest:
            this, rest = rest[:7], rest[7:]
            if seq > 0 and rest:
                # never skip first or last serie
                if this != '\x00\x00\x00\x00\x00\x00\x00':
                    this += chr(yubikey_defs.SLOT_WRITE_FLAG + seq)
                    out.append(self._debug_string(debug, this))
            else:
                this += chr(yubikey_defs.SLOT_WRITE_FLAG + seq)
                out.append(self._debug_string(debug, this))
            seq += 1
        return out

    def _debug_string(self, debug, data):
        """
        Annotate a frames data, if debug is True.
        """
        if not debug:
            return data
        if self.command in [yubikey_config.SLOT_CONFIG,
                            yubikey_config.SLOT_CONFIG2,
                            yubikey_config.SLOT_UPDATE1,
                            yubikey_config.SLOT_UPDATE2,
                            yubikey_config.SLOT_SWAP,
                            ]:
            # annotate according to config_st (see yubikey_config.to_string())
            if ord(data[-1]) == 0x80:
                return (data, "FFFFFFF")
            if ord(data[-1]) == 0x81:
                return (data, "FFFFFFF")
            if ord(data[-1]) == 0x82:
                return (data, "FFUUUUU")
            if ord(data[-1]) == 0x83:
                return (data, "UKKKKKK")
            if ord(data[-1]) == 0x84:
                return (data, "KKKKKKK")
            if ord(data[-1]) == 0x85:
                return (data, "KKKAAAA")
            if ord(data[-1]) == 0x86:
                return (data, "AAlETCr")
            if ord(data[-1]) == 0x87:
                return (data, "rCR")
            # after payload
            if ord(data[-1]) == 0x89:
                return (data, " Scr")
        else:
            return (data, '')