docs: def info(ctx):
      """
      Display status of PIV application.
      """
      controller = ctx.obj['controller']
      click.echo('PIV version: %d.%d.%d' % controller.version)
  
      # Largest possible number of PIN tries to get back is 15
      tries = controller.get_pin_tries()
      tries = '15 or more.' if tries == 15 else tries
      click.echo('PIN tries remaining: %s' % tries)
      if controller.puk_blocked:
          click.echo('PUK blocked.')
      if controller.has_derived_key:
          click.echo('Management key is derived from PIN.')
      if controller.has_stored_key:
          click.echo('Management key is stored on the YubiKey, protected by PIN.')
      try:
          chuid = b2a_hex(controller.get_data(OBJ.CHUID)).decode()
      except APDUError as e:
          if e.sw == SW.NOT_FOUND:
              chuid = 'No data available.'
      click.echo('CHUID:\t' + chuid)
  
      try:
          ccc = b2a_hex(controller.get_data(OBJ.CAPABILITY)).decode()
      except APDUError as e:
          if e.sw == SW.NOT_FOUND:
              ccc = 'No data available.'
      click.echo('CCC: \t' + ccc)
  
      for (slot, cert) in controller.list_certificates().items():
          click.echo('Slot %02x:' % slot)
  
          try:
              # Try to read out full DN, fallback to only CN.
              # Support for DN was added in crytography 2.5
              subject_dn = cert.subject.rfc4514_string()
              issuer_dn = cert.issuer.rfc4514_string()
              print_dn = True
          except AttributeError:
              print_dn = False
              logger.debug('Failed to read DN, falling back to only CNs')
              subject_cn = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)
              subject_cn = subject_cn[0].value if subject_cn else 'None'
              issuer_cn = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME)
              issuer_cn = issuer_cn[0].value if issuer_cn else 'None'
          except ValueError as e:
              # Malformed certificates may throw ValueError
              logger.debug('Failed parsing certificate', exc_info=e)
              click.echo('\tMalformed certificate: {}'.format(e))
              continue
  
          fingerprint = b2a_hex(cert.fingerprint(hashes.SHA256())).decode('ascii')
          algo = ALGO.from_public_key(cert.public_key())
          serial = cert.serial_number
          not_before = cert.not_valid_before
          not_after = cert.not_valid_after
  
          # Print out everything
          click.echo('\tAlgorithm:\t%s' % algo.name)
          if print_dn:
              click.echo('\tSubject DN:\t%s' % subject_dn)
              click.echo('\tIssuer DN:\t%s' % issuer_dn)
          else:
              click.echo('\tSubject CN:\t%s' % subject_cn)
              click.echo('\tIssuer CN:\t%s' % issuer_cn)
          click.echo('\tSerial:\t\t%s' % serial)
          click.echo('\tFingerprint:\t%s' % fingerprint)
          click.echo('\tNot before:\t%s' % not_before)
          click.echo('\tNot after:\t%s' % not_after)