def do_exec(args): state = load_state_file(args.filename) while True: try: yk = yubico.find_yubikey(debug=args.debug) for k in state.keys(): if state[k]['type'] != 'HMAC-SHA1': logging.debug("Unknown type '%s' for '%s'" % (state[k]['type'], k)) continue if state[k]['encryption'] != 'AES-CBC': logging.debug("Unknown encryption '%s' for '%s'" % (state[k]['encryption'], k)) continue if do_challenge(yk, state[k]): logging.info("Authenticated with key '%s'" % k) write_state_file(args.filename, state) os.execvp(args.command[0], args.command) logging.error("Exec Error!") return 1 except Exception as e: logging.info("Error finding yubikey: %s" % str(e)) time.sleep(1)
def make_totp(): # adapted from Yubico try: YK = yubico.find_yubikey() print YK # Do challenge-response current_time = int(time.time()) challenge = struct.pack("> Q", current_time / STEP).ljust(64, chr(0x0)) print "Sending challenge : %s" % (challenge.encode('hex')) print "Press button if you configured your Yubikey Slot 2 to require user input." response = YK.challenge_response(challenge, slot=SLOT) print "Response received : %s" % (response.encode('hex')) # format with appropriate number of leading zeros fmt = "%." + str(DIGITS) + "i" totp_str = fmt % (yubico.yubico_util.hotp_truncate(response, length=DIGITS)) print "Response formatted and truncated to %d digits: %s" % (DIGITS, totp_str) write_to_clipboard(totp_str) gtk.timeout_add(TIME_CLEAR * 1000, clear_totp) except yubico.yubico_exception.YubicoError, e: print "ERROR: %s" % (e.reason) notify_error = pynotify.Notification( "Yubikey for Google Authenticator", "ERROR: %s" % (e.reason), ICON) notify_error.show() return 1
def test3(): '''Tests the HMAC-SHA1. Requires a YubiKey with OTP challenge-response configured in slot 2. ''' try: key = yubico.find_yubikey(debug=False) print key.challenge_response(('\x00' * 63) + '\x01', mode='HMAC', slot=2, may_block=True).encode('hex') print key.challenge_response(('\x00' * 62) + '\x01', mode='HMAC', slot=2, may_block=True).encode('hex') print key.challenge_response(('\x00' * 62) + '\x01\x00', mode='HMAC', slot=2, may_block=True).encode('hex') print key.challenge_response('', mode='HMAC', slot=2, may_block=True).encode('hex') print key.challenge_response('\x00', mode='HMAC', slot=2, may_block=True).encode('hex') print key.challenge_response('\x00' * 64, mode='HMAC', slot=2, may_block=True).encode('hex') except yubico.yubico_exception.YubicoError as e: print e.reason sys.exit(1)
def get_yubikey(): try: return find_yubikey(debug = False) except YubiKeyError: return None except USBError: return None
def update(self): try: self.__keystate = "YubiKey: " + str( yubico.find_yubikey(debug=False).serial()) except yubico.yubico_exception.YubicoError: self.__keystate = "No YubiKey" except Exception: self.__keystate = "n/a"
def find_tokens(): """Iterate over all available tokens.""" for skip in range(256): try: yield yubico.find_yubikey(skip=skip) except yubico.yubikey.YubiKeyError: pass except usb.USBError: pass
def find(slot=1): """Iterate over all available YubiKeys using skip parameter.""" for skip in range(256): try: yield YubiKey(yubico.find_yubikey(skip=skip), slot) except yubico.yubikey.YubiKeyError, error: if error.reason == 'No YubiKey found': break # no more YubiKeys except usb.USBError: pass
def configure_token(secret, slot=1): """Configures Token in OATH-HOTP challenge-response with secret.""" try: token = yubico.find_yubikey() cfg = token.init_config() cfg.mode_challenge_response(secret, type='HMAC', variable=True, require_button=False) cfg.extended_flag('SERIAL_API_VISIBLE', True) token.write_config(cfg, slot=slot) except yubico.yubikey.YubiKeyError, error: print 'Configuration failed: %s' % str(error) return False
def _getYubikey(self): try: skip = 0 while skip < 5: yubikey = yubico.find_yubikey(skip=skip) skip += 1 except yubico.yubikey.YubiKeyError: pass if skip == 0: raise ValueError("No yubikey were found") if skip > 1: raise ValueError("Too many yubikey:s were found") return yubikey
def get_response(challenge): try: YK = yubico.find_yubikey() response = YK.challenge_response(challenge.encode(), slot=2) except yubico.yubico_exception.YubicoError as inst: print("ERROR: %s" % inst.reason) return "" # Workaround for http://bugs.python.org/issue24596 del YK hexresponse = yubico.yubico_util.hexdump(response, length=20).strip("0000") formattedresponse = "".join(hexresponse.split()) return formattedresponse
def get_response(challenge): try: YK = yubico.find_yubikey() response = YK.challenge_response(challenge.encode(), slot=2) except yubico.yubico_exception.YubicoError as inst: print(("ERROR: %s" % inst.reason)) return '' # Workaround for http://bugs.python.org/issue24596 del YK hexresponse = yubico.yubico_util.hexdump(response, length=20).strip('0000') formattedresponse = ''.join(hexresponse.split()) return formattedresponse
def detect_yubikey(self): """Tries to detect a plugged-in YubiKey else alerts user""" try: self.yk = yubico.find_yubikey() self.version.set("Version:%s" % self.yk.version()) self.serial.set("Serial:%s" % self.yk.serial()) except yubico.yubikey.YubiKeyError: self.version.set("No YubiKey detected") self.serial.set("") self.yk = None except yubico.yubikey_usb_hid.usb.USBError as e: self.version.set("No YubiKey detected") self.serial.set("") self.user_message.set( "A USB error occurred:%s - do you have permission to access USB devices?", e.message )
def _getYubikey(self): try: skip = 0 while skip < 5: yk = yubico.find_yubikey(skip=skip) if yk is not None: self._yubikey = yk # Assumes that only one yubikey could be found. skip += 1 except yubico.yubikey.YubiKeyError: pass if skip == 0: self._yubikey = None raise ValueError("No yubikey were found") if skip > 1: self._yubikey = None raise ValueError("Too many yubikey:s were found") self._yubikeyVersion = self._yubikey.version()
def test1(): '''Tests the OTP1 protocol. Requires a YubiKey with OTP challenge-response configured in slot 2. The key should be a 16-byte, all-zero string. ''' bc = AES.new(test_key[:16]) # Fake previous frame (for testing). last_frame = otp.Frame(bc.block_size) # Test OTP validation. p = "beefbeefbeeflctgglfhfgnekelfhvhufjretgdnhvkf" (id, frame) = otp.Frame.from_otp(bc, p) assert frame.ok() # Check CRC assert last_frame < frame # Check the counter is fresh assert frame.payload == '\x00' * 6 # Check that the private ID matches assert frame.get_otp(bc, id) == p # Test get_otp() # Test OTP1 protocol. This uses the OTP challenge-response protocol. try: key = yubico.find_yubikey(debug=False) h = SHA256.new() h.update('woodland') challenge = h.digest()[:6] for i in range(10): enciphered_frame = key.challenge_response(challenge, mode='OTP', slot=2) raw_frame = bc.decrypt(enciphered_frame) frame = otp.Frame(raw_frame) assert frame.ok() assert last_frame < frame assert frame.payload == challenge last_frame = frame except yubico.yubico_exception.YubicoError as e: print e.reason sys.exit(1)
def Program(): try: yk = yubico.find_yubikey(debug=False) print("Version : %s " % yk.version()) except yubico.yubico_exception.YubicoError as e: print("ERROR: %s" % e.reason) return cfg = yk.init_config() key = binascii.hexlify(os.urandom(16)) keyFixed = binascii.hexlify(os.urandom(16)) cfg.aes_key("h:" + key.decode("utf-8")) cfg.config_flag('STATIC_TICKET', True) cfg.fixed_string("h:" + keyFixed.decode("utf-8")) yk.write_config(cfg, slot=1) # Predict aes128 result and add the fixed key ## This is a static key, no idea where it comes from. fixed = b'000000000000ffffffffffffffff0f2e' enc = AES.new(binascii.unhexlify(key), AES.MODE_CBC, b'\x00' * 16) data = enc.encrypt(binascii.unhexlify(fixed)) # translate #key = binascii.hexlify(os.urandom(16)) try: # Python 2 maketrans = string.maketrans except AttributeError: # Python 3 maketrans = bytes.maketrans t_map = maketrans(b"0123456789abcdef", b"cbdefghijklnrtuv") outKey = binascii.hexlify(data).translate(t_map).decode("utf-8") outKeyFixed = keyFixed.decode("utf-8").translate(t_map) print("The whole key is: {}{}".format(outKeyFixed, outKey))
def yubikey_passphrase_cr(passphrase): """ This function: Takes an input passphrase generates the SHAd256 hash of it sends that hash to a Yubikey configured for HMAC-SHA1 on slot 2 computes the whirlpool hash of the HMAC-SHA1 response received from the Yubikey returns the whirlpool hash :param passphrase: passphrase (plaintext) :type passphrase: str :return: whirlpool digest (hex) :rtype: str """ try: import yubico except ImportError: yubico = None if not yubico: del yubico return passphrase try: yubikey = yubico.find_yubikey() except yubico.yubikey.YubiKeyError: return passphrase if yubikey: challenge = SHAd256.new(passphrase).hexdigest() print('[YubiKey] Sending challenge') try: response = yubikey.challenge_response(challenge, slot=YUBIKEY_HMAC_CR_SLOT) print('[YubiKey] Got response') except yubico.yubikey.YubiKeyTimeout: print('[YubiKey] Timeout. Not using Yubikey.') return passphrase passphrase = whirlpool.new(response).hexdigest() return passphrase
def make_totp(): # adapted from Yubico try: YK = yubico.find_yubikey() print YK # Do challenge-response current_time = int(time.time()) challenge = struct.pack("> Q", current_time / STEP).ljust(64, chr(0x0)) print "Sending challenge : %s" % (challenge.encode('hex')) print "Press button if you configured your Yubikey Slot 2 to require user input." response = YK.challenge_response(challenge, slot=SLOT) print "Response received : %s" % (response.encode('hex')) # format with appropriate number of leading zeros fmt = "%." + str(DIGITS) + "i" totp_str = fmt % (yubico.yubico_util.hotp_truncate(response, length=DIGITS)) print "Response formatted and truncated to %d digits: %s" % (DIGITS, totp_str) write_to_clipboard(totp_str) gtk.timeout_add(TIME_CLEAR * 1000, clear_totp) except yubico.yubico_exception.YubicoError, e: print "ERROR: %s" % (e.reason) notify_error = pynotify.Notification("Yubikey for Google Authenticator","ERROR: %s" % (e.reason), ICON) notify_error.show() return 1
def __init__(self): self._yubikey = yubico.find_yubikey(debug=False)
def forward(self, *args, **kwargs): # Open the YubiKey try: yk = yubico.find_yubikey() except usb.core.USBError as e: raise NotFound(reason="No YubiKey found: %s" % e.strerror) except yubico.yubikey.YubiKeyError as e: raise NotFound(reason=e.reason) assert yk.version_num() >= (2, 1) # If no slot is specified, find the first free slot. if kwargs.get('slot', None) is None: try: used = yk.status().valid_configs() kwargs['slot'] = sorted({1, 2}.difference(used))[0] except IndexError: raise NotFound(reason=_('No free YubiKey slot!')) # Create the key (NOTE: the length is fixed). key = os.urandom(20) # Write the config. cfg = yk.init_config() cfg.mode_oath_hotp(key, kwargs['ipatokenotpdigits']) cfg.extended_flag('SERIAL_API_VISIBLE', True) yk.write_config(cfg, slot=kwargs['slot']) # Filter the options we want to pass. options = {k: v for k, v in kwargs.items() if k in ( 'version', 'description', 'ipatokenowner', 'ipatokendisabled', 'ipatokennotbefore', 'ipatokennotafter', 'ipatokenotpdigits', )} # Run the command. answer = self.Backend.rpcclient.forward('otptoken_add', *args, type=u'hotp', ipatokenvendor=u'YubiCo', ipatokenmodel=unicode(yk.model), ipatokenserial=unicode(yk.serial()), ipatokenotpalgorithm=u'sha1', ipatokenhotpcounter=0, ipatokenotpkey=key, no_qrcode=True, **options) # Suppress values we don't want to return. for k in (u'uri', u'ipatokenotpkey'): if k in answer.get('result', {}): del answer['result'][k] # Return which slot was used for writing. answer.get('result', {})['slot'] = kwargs['slot'] return answer
import requests r = requests.get("http://192.168.1.2:8080/ccapi/ver100/contents/sd/100CANON") r.json()["url"][-1] from PIL import Image from io import BytesIO i = Image.open(BytesIO(r.content)) i from simple_websocket_server import WebSocketServer, WebSocket import sys import yubico from yubico_client import Yubico try: yubikey = yubico.find_yubikey(debug=False) print( "Version : %s " % yubikey.version()) except yubico.yubico_exception.YubicoError as e: print( "ERROR: %s" % e.reason) sys.exit(1) client = Yubico('client id', 'secret key') client.verify('otp')
def forward(self, *args, **kwargs): # Open the YubiKey try: yk = yubico.find_yubikey() except usb.core.USBError as e: raise NotFound(reason="No YubiKey found: %s" % e.strerror) except yubico.yubikey.YubiKeyError as e: raise NotFound(reason=e.reason) assert yk.version_num() >= (2, 1) # If no slot is specified, find the first free slot. if kwargs.get('slot', None) is None: try: used = yk.status().valid_configs() kwargs['slot'] = sorted({1, 2}.difference(used))[0] except IndexError: raise NotFound(reason=_('No free YubiKey slot!')) # Create the key (NOTE: the length is fixed). key = os.urandom(20) # Write the config. cfg = yk.init_config() cfg.mode_oath_hotp(key, kwargs['ipatokenotpdigits']) cfg.extended_flag('SERIAL_API_VISIBLE', True) yk.write_config(cfg, slot=kwargs['slot']) # Filter the options we want to pass. options = { k: v for k, v in kwargs.items() if k in ( 'version', 'description', 'ipatokenowner', 'ipatokendisabled', 'ipatokennotbefore', 'ipatokennotafter', 'ipatokenotpdigits', ) } # Run the command. answer = self.Backend.rpcclient.forward( 'otptoken_add', *args, type=u'hotp', ipatokenvendor=u'YubiCo', ipatokenmodel=unicode(yk.model), ipatokenserial=unicode(yk.serial()), ipatokenotpalgorithm=u'sha1', ipatokenhotpcounter=0, ipatokenotpkey=key, no_qrcode=True, **options) # Suppress values we don't want to return. for k in (u'uri', u'ipatokenotpkey'): if k in answer.get('result', {}): del answer['result'][k] # Return which slot was used for writing. answer.get('result', {})['slot'] = kwargs['slot'] return answer
""" 2021: This code gives "Access denied (insufficient permissions) when the yubikey is plugged in. No good. """ import sys import yubico try: yubikey = yubico.find_yubikey() print("Version: {}".format(yubikey.version())) except yubico.yubico_exception.YubicoError as e: print("ERROR: {}".format(e.reason)) sys.exit(1)
import sys import yubico expected = \ b'\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82' + \ b'\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24' # turn on YubiKey debug if -v is given as an argument debug = False if len(sys.argv) > 1: debug = (sys.argv[1] == '-v') # Look for and initialize the YubiKey try: YK = yubico.find_yubikey(debug=debug) print("Version : %s " % YK.version()) print("Serial : %i" % YK.serial()) print("") # Do challenge-response secret = b'Sample #2'.ljust(64, b'\0') print("Sending challenge : %s\n" % repr(secret)) response = YK.challenge_response(secret, slot=2) except yubico.yubico_exception.YubicoError as inst: print("ERROR: %s" % inst.reason) sys.exit(1) print("Response :\n%s\n" % yubico.yubico_util.hexdump(response))
""" Set up a YubiKey with a NIST PUB 198 A.2 20 bytes test vector in Slot 2 (variable input) """ import sys import struct import yubico import six slot = 2 try: YK = yubico.find_yubikey(debug=True) # print("Version : %s " % YK.version()) Cfg = YK.init_config() key = b'h:303132333435363738393a3b3c3d3e3f40414243' Cfg.mode_challenge_response(key, type='HMAC', variable=True) Cfg.extended_flag('SERIAL_API_VISIBLE', True) user_input = six.moves.input( 'Write configuration to slot %i of YubiKey? [y/N] : ' % slot) if user_input in ('y', 'ye', 'yes'): YK.write_config(Cfg, slot=slot) print("\nSuccess!") else: print("\nAborted") except yubico.yubico_exception.YubicoError as inst: print("ERROR: %s" % inst.reason) sys.exit(1)