Code Monkey home page Code Monkey logo

googlechromelabs / chromeos_smart_card_connector Goto Github PK

View Code? Open in Web Editor NEW
133.0 33.0 51.0 182.45 MB

Smart Card Connector App for Chrome OS

Home Page: https://chrome.google.com/webstore/detail/smart-card-connector/khpfeaanjngmcnplbdlpegiifgpfgdco

License: Apache License 2.0

Shell 0.78% Makefile 8.03% C++ 50.06% C 0.27% JavaScript 36.58% HTML 1.13% CSS 0.61% Python 2.37% Lua 0.11% PHP 0.06%
smartcard chromeos chrome-extension pcsc chrome-os javascript cpp nacl webassembly emscripten

chromeos_smart_card_connector's Introduction

Smart Card Connector App for ChromeOS

This repository contains sources of the ChromeOS Smart Card Connector App (distributed at https://chrome.google.com/webstore/detail/smart-card-connector/khpfeaanjngmcnplbdlpegiifgpfgdco) and examples how programs can communicate with this app.

Documentation

This documentation is split into several parts for different target audiences:

FAQ

What is a smart card?

Please refer to https://en.wikipedia.org/wiki/Smart_card.

Note that there also some devices that emulate a smart card, e.g., some of Yubikey devices (see https://www.yubico.com/authentication-standards/smart-card/).

Do I need the Smart Card Connector App?

You only need this in case you have a smart card (or a device that emulates it) and need to use it on your ChromeOS device for authenticating at web pages, remote desktop applications, logging into ChromeOS in enterprise deployments, etc.

Can I use it with my memory card (microSD, etc.)?

No. The Smart Card Connector App is only useful with smart cards.

chromeos_smart_card_connector's People

Contributors

annklr avatar ayanader avatar dskaram avatar emaxx-google avatar fabian-sommer avatar fabianhenneke avatar id-melon avatar ivansandrk avatar ludovicrousseau avatar qmx avatar swapnil119 avatar vapier avatar viktoriiakovalova avatar xtralogic avatar yoe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chromeos_smart_card_connector's Issues

Stop USB communication when the Chrome OS user session is locked

The Smart Card Connector app should monitor the Chrome OS session state and, if it's running in-session and the session becomes locked, it should stop talking to the smart card readers. If we don't do this, then the users that use smart cards for logging into Chrome OS won't be able to unlock their session, since the Lock Screen implementation talks to another instance of the app that runs in the sign-in profile context, but only one app can talk to a single USB device at a time.

The chrome.loginState API can be used for getting all the needed information: https://cs.chromium.org/chromium/src/chrome/common/extensions/api/login_state.idl

Fix crash when USB device numbers reach 256

Currently, the Smart Card Connector crashes once it receives a USB device number from Chrome that exceeds 255.

Such big numbers don't occur usually, since Chrome just uses an internal counter that gets incremented for every new device, but nevertheless these values may be reached if the Chromebook doesn't get rebooted over a long period of time and the user plugs and unplugs devices many times in between.

The crash happens due to hitting the assertion when the value received from Chrome cannot be casted into the 8-bit number used by libusb:

// FIXME(emaxx): Fix the implementation to re-use the free device identifiers.

As was written in the comment in the code, one way for fixing this problem is adding code that starts reusing the device numbers once we hit the boundary (e.g., by keeping the track of the most recently used device numbers).

Add retry logic into reader initialization code

Currently, the Smart Card Connector app only makes a single attempt to connect to each USB device.

We should change this to be more bulletproof by retrying the connection attempts (possibly, with an exponential backoff).

Failed to open device OMNIKEY AG CardMan 3121 on Linux

Hi,

I was trying to use the Smart Card Connector App in Ubuntu 16.04, with a OmniKey CarMand 3021 plugged in. The smart card reader is working with Firefox.

This error show up upon adding permissions to the reader.

image

Here are the logs:

 [  0.038s] [<background page>.GoogleSmartCard.ConnectorApp.BackgroundMain] [INFO] The Smart Card Connector app (id "khpfeaanjngmcnplbdlpegiifgpfgdco", version 1.2.3.0) background script started
 [  0.059s] [<background page>.GoogleSmartCard.ConnectorApp.BackgroundMain] [INFO] Created a new PC/SC-Lite client handler (id 0) for handling requests from own app
 [  0.065s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">] [INFO] Loading NaCl module...
 [  0.102s] [<background page>.GoogleSmartCard.Libusb.ChromeUsbBackend] [INFO] 1 USB device(s) available: [{device: 0x00, manufacturerName: "OMNIKEY AG", productId: 0x00003021, productName: "Smart Card Reader USB", serialNumber: "", vendorId: 0x0000076B, version: 0x00000302}]
 [  0.194s] [<background page>.GoogleSmartCard.PcscLiteServerClientsManagement.ClientHandler<id=0, client=own app>] [INFO] Delaying the received requests until the PC/SC-Lite server gets ready. Currently delayed requests: SCardEstablishContext(<stripped value>, <stripped value>, <stripped value>)
 [  0.562s] [</window.html>.GoogleSmartCard.ConnectorApp.MainWindow] [INFO] The main window is created
 [  0.569s] [</window.html>.GoogleSmartCard.ConnectorApp.MainWindow] [INFO] Displaying 0 card reader(s): []
 [  1.344s] [</window.html>.GoogleSmartCard.ConnectorApp.MainWindow] [INFO] Displaying the warning regarding non-Chrome OS system (the current OS is "linux")
 [  1.347s] [<background page>.GoogleSmartCard.PcscLiteServerClientsManagement.PermissionsChecking.ManagedRegistry] [INFO] Loaded managed storage data with the allowed client App ids: Set{}
 [  1.349s] [<background page>.GoogleSmartCard.PcscLiteServerClientsManagement.PermissionsChecking.UserPromptingChecker] [INFO] Loaded local storage data with the stored user selections: no data
 [  6.280s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">] [INFO] Successfully loaded NaCl module
 [  6.299s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.ReaderTracker] [INFO] A new reader "OMNIKEY AG CardMan 3121" (port 2097152, device "usb:076b/3021:libusb-1.0:42:0:0") is being initialized...
 [  6.302s] [</window.html>.GoogleSmartCard.ConnectorApp.MainWindow] [INFO] Displaying 1 card reader(s): [{name: "OMNIKEY AG CardMan 3121", status: "init", error: undefined, isCardPresent: false}]
 [  6.305s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000000 ../../src/src/ifdhandler.c:1953:init_driver() Driver version: 1.4.24
 [  6.306s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000930 ../../src/src/ifdhandler.c:1970:init_driver() LogLevel: 0x0003
 [  6.307s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000100 ../../src/src/ifdhandler.c:1981:init_driver() DriverOptions: 0x0004
 [  6.307s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000300 ../../src/src/ifdhandler.c:110:CreateChannelByNameOrChannel() Lun: 0, device: usb:076b/3021:libusb-1.0:42:0:0
 [  6.308s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000070 ../../src/src/ccid_usb.c:287:OpenUSBByName() Using: /crx/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
 [  6.309s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000830 ../../src/src/ccid_usb.c:305:OpenUSBByName() ifdManufacturerString: Ludovic Rousseau ([email protected])
 [  6.310s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000090 ../../src/src/ccid_usb.c:306:OpenUSBByName() ifdProductString: Generic CCID driver
 [  6.312s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000050 ../../src/src/ccid_usb.c:307:OpenUSBByName() Copyright: This driver is protected by terms of the GNU Lesser General Public License version 2.1, or (at your option) any later version.
 [  6.321s] [<background page>.GoogleSmartCard.Libusb.ChromeUsbRequestHandler] [WARNING] API error occurred while calling chrome.usb.openDevice(<stripped value>): Failed to open device.
 [  6.325s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [WARNING] LibusbOverChromeUsb::LibusbOpen request failed: Error: Failed to open device.
 [  6.326s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [WARNING] [syslog] 00022720 ../../src/src/ccid_usb.c:525:OpenUSBByName() Can't libusb_open(42/0): LIBUSB_ERROR_OTHER
 [  6.327s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000360 ../../src/src/ccid_usb.c:189:close_libusb_if_needed() libusb_exit
 [  6.328s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] 00000140 ../../src/src/ccid_usb.c:749:OpenUSBByName() Device not found?
 [  6.329s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [WARNING] [syslog] 00000130 ../../src/src/ifdhandler.c:144:CreateChannelByNameOrChannel() failed
 [  6.330s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] ../../../../../third_party/pcsc-lite/src/src/readerfactory.c:1110:RFInitializeReader() Open Port 0x200000 Failed (usb:076b/3021:libusb-1.0:42:0:0)
 [  6.331s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [syslog] ../../../../../third_party/pcsc-lite/src/src/readerfactory.c:375:RFAddReaderOriginal() OMNIKEY AG CardMan 3121 init failed.
 [  6.332s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.ReaderTracker] [WARNING] Failure while initializing the reader "OMNIKEY AG CardMan 3121" (port 2097152, device "usb:076b/3021:libusb-1.0:42:0:0"): error code 0x80100009
 [  6.333s] [</window.html>.GoogleSmartCard.ConnectorApp.MainWindow] [INFO] Displaying 1 card reader(s): [{name: "OMNIKEY AG CardMan 3121", status: "failure", error: "0x80100009", isCardPresent: false}]
 [  6.334s] [<background page>.GoogleSmartCard.PcscLiteServerClientsManagement.ClientHandler<id=0, client=own app>] [INFO] The server is ready, processing the delayed requests...
 [  6.338s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardEstablishContext(dwScope=SCARD_SCOPE_SYSTEM, pvReserved1=null, pvReserved2=null): called...
 [  6.339s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardEstablishContext: returning 0x00000000 ["Command successful."], hContext=0x5851F42D
 [  6.344s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardListReaders(hContext=0x5851F42D, mszGroups=null): called...
 [  6.345s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardListReaders: returning 0x8010002E ["Cannot find a smart card reader."]
 [  6.351s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardGetStatusChange(hContext=0x5851F42D, dwTimeout=0, rgReaderStates=NULL): called...
 [  6.351s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardGetStatusChange: returning 0x00000000 ["Command successful."], rgReaderStates=NULL
 [  6.354s] [<background page>.GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [INFO] [PC/SC-Lite client 0 handler] SCardGetStatusChange(hContext=0x5851F42D, dwTimeout=60000, rgReaderStates=0xFEB13A80([SCARD_READERSTATE(szReader="\\?PnP?\Notification", pvUserData=NULL, dwCurrentState=SCARD_STATE_UNAWARE)])): called...

Permission dialog should be automatically closed and resolved when the managed policy gets updated

Currently, when the managed policy gets updated, it has no influence on the previous requests that are blocked waiting for user decision (i.e. until it presses "Allow" or "Block").

Instead, if the updated managed policy contains values that correspond to the previously attempted permission requests, they should become immediately resolved by the Connector app.

P.S. This issue produces problems mostly when running on the login screen: it may be that the applications will be installed and started before the actual value for the managed policy is received.

App crash-restart loop caused by bad data stored for user selection

Steps to reproduce:

  1. Install the Connector app.
  2. Install at least two middleware apps that talk to the Connector app. Press "Allow" in both prompts about granting permissions to them.

Expected:
This works.

Actual:
The Connector app crashes and fails to start due to a fatal error during initialization. After several crash-restart loops, the browser disables the App.

Workaround:
Uninstall the Connector and install it back.

/cc @dskaram

Display/allow to edit stored user decisions regarding client Apps permissions

There are two ways for a client app to be granted permission to communicate with the smart card.

  1. Via admin policy.
  2. By user Allowing explicitly through dialog in absence of policy.

For #2, the user has no way of revoking that permission once granted. We want to add a small link next to the connected app (that appears when the user hovers over the connected app's string) that says "Revoke permission". If that app tries to connect to the connector again, the connector should show the permission dialog again allowing the user to Allow or Deny the request.

Frequently reused PC/SC handles

The PC/SC server ran by the Smart Card Connector app seems to reuse the same numeric values for PC/SC session or card handles too frequently. Those handles are intended to be random, so while this reuse doesn't present an immediate problem, it may slightly affect security protection or lead to unexpected situations in client applications (in case they aren't handling such situations correctly).

Moreover, it's even not that rare that the same numeric value is exposed as both a session handle and a card handle at the same time. While this is still technically valid, client applications may not be coded carefully enough to handle this situation.

Therefore we need to make sure that the PC/SC handles returned by the Connector app are fully random.

Stop building our libraries separately

Currently, the build process is organized in a way that each sub-library (like //common/cpp) is built separately and then has its .lib+.h files installed into a common place (in the NaCl environment). The .lib files are then used when linking the resulting executable.

The original motivation behind this approach is pretty much described in issue #132; additionally, it allows to avoid recompiling a library multiple times for different executables and to test it without compiling the rest of the code. However, similar to that issue, the benefits of that approach don't outweigh the complexity and the fragility caused by it.

Therefore the suggestion is to get rid of that model and separate .lib files, and instead directly compile every library's source file as part of the resulting target.

unable to recognize card reader

the application is unable to recognize card reader pcProx by RFIDeas device id c27:3bfa.

The device is recognized by the ChromeOS but not the application. we have used other commercial connectors like QwickACCESS and they recognize the reader but not the smart card connector app. We would like to use an opensource version rather than a commercial one.

Fix NaCl initialization issues when running on desktop OSes

Currently, usage of the "make run"/"make test" commands in the repository is burdened due to NaCl initialization errors returned by Chrome.

The errors are transient and go away after waiting for ~1 minute, but it's still making the development process much more cumbersome.

Meanwhile we don't officially support the Smart Card Connector app on non Chrome OS systems, we could look into fixing that issue in order to simplify development experience.

One potential idea is to add retries into our JS code that loads NaCl modules.

Document Connector App API

Currently, the API exposed by the Connector App is described in the root README file only briefly.

We should find a way to document it properly (including the details of how structured data and raw data are serialized). Probably, JSON Schema should be used.

The app doesn't find any smart card reader under OS X

Hi!

When using a middleware extension to connect with the connector app in OS X, it never finds any reader (when calling SCardListReaders). I tried this with CACKey, and an app I'm developing right now for a research project which connects to a smart card (specifically a DNIE from Spain), and I haven't had any luck with these two.

I attach a log which was printed in the console of the extension's background script:

[34761.582s] [GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [PC/SC-Lite client 1 handler] SCardEstablishContext(dwScope=SCARD_SCOPE_SYSTEM, pvReserved1=null, pvReserved2=null): called...
[34761.583s] [GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [PC/SC-Lite client 1 handler] SCardEstablishContext: returning 0x00000000 ["Command successful."], hContext=0x5851F42D
[34761.584s] [GoogleSmartCard.PcscLiteServerClientsManagement.ClientHandler<id=1, app_id="lpimdiknnpijeigckalekdccibdmeojg">] The remote call request SCardEstablishContext(<stripped value>, <stripped value>, <stripped value>) finished successfully
[34761.643s] [GoogleSmartCard.PcscLiteServerClientsManagement.ClientHandler<id=1, app_id="lpimdiknnpijeigckalekdccibdmeojg">] Received a remote call request: SCardListReaders(<stripped value>, <stripped value>)
[34761.649s] [GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [PC/SC-Lite client 1 handler] SCardListReaders(hContext=0x5851F42D, mszGroups=null): called...
[34761.650s] [GoogleSmartCard.NaclModule<"nacl_module.nmf">.NaCl] [PC/SC-Lite client 1 handler] SCardListReaders: returning 0x8010002E ["Cannot find a smart card reader."]
[34761.651s] [GoogleSmartCard.PcscLiteServerClientsManagement.ClientHandler<id=1, app_id="lpimdiknnpijeigckalekdccibdmeojg">] The remote call request SCardListReaders(<stripped value>, <stripped value>) finished successfully

One more detail: when I run pcsctest from the Mac terminal, however, it works perfectly.

Adrias-iMac:~ adria$ pcsctest

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Alcor Micro AU9520
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Alcor Micro AU9520
Current Reader State             : 0x54
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 20 (0x14)
Current Reader ATR Value         : 3B 7F 38 00 00 00 6A 44 4E 49 65 10 02 4C 34 01 13 03 90 00 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.
Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Alcor Micro AU9520
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Alcor Micro AU9520
Current Reader State             : 0x54
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 20 (0x14)
Current Reader ATR Value         : 3B 7F 38 00 00 00 6A 44 4E 49 65 10 02 4C 34 01 13 03 90 00 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.

PC/SC Test Completed Successfully !

Some info about my OS/browser:
Chrome 52.0.2743.49 beta
Smart Card Connector 1.0.4.0 (but I could also reproduce this problem with version 1.0.3.0, I have not tried other versions)
OS X 10.11.6

Thank you very much in advance :)

A reader is not removed when it is physically disconnected

When a reader is disconnected it is not removed from the UI and also continues to be reported to the client apps. When the reader reconnected, it does not work.
This affects only Beta and Dev Chrome OS channels, the Stable channel works fine.

Steps to reproduce
-Install and launch the Smart Card Conenctor app.
-Connect a reader to a USB port, it is recognized and shown in the app UI correctly. Insert/remove a smart card, the reader icon changes accordingly.
-Disconnect the reader, it remains shown in the UI and continues to be reported to the client apps.
-Connect the reader back, the reader is still shown, but the icon does not change when a smart card inserted/removed.
-The only way to clear the condition is to re-install the Smart Card Connector app or reboot the Chromebook.
-This was reproduced with two different Smart card readers.
-If a second smart card reader is connected after the first one disconnected, the second one is is not shown as if the app just hung.

Environment details:
Chromebook Pixel, model C0A.
The Smart Card Connector app (id "khpfeaanjngmcnplbdlpegiifgpfgdco", version 1.2.22.0)
Stable channel: Chrome OS 74.0.3729.125
Beta channel: Chrome OS 75.0.3770.24
Dev channel: Chrome OS 75.0.3770.19
USB Smart card readers tested:
"Gemalto PC Twin Reader" "vendorId": 0x000008E6, "productId": 0x00003437
"Alcor Micro AU9560" "vendorId": 0x0000058F, "productId": 0x00009540

smart-card-connector-log-bad-dev-channel-chrome-75.0.3770.19.txt
smart-card-connector-log-good-stable-channel-chrome-74.0.3279.125.txt
smart-card-connector-log-bad-beta-channel-chrome-75.0.3770.24.txt

SCardTransmit returns SCARD_PROTOCOL_ANY as the receive protocol

When the SCardTransmit function is called (either from JavaScript or from the NaCl client wrapper) without specified the desired receive protocol (this parameter is called pioRecvPci in the PC/SC-Lite C API), then our NaCl port returns with specifying the receive protocol as 3 (that is, SCARD_PROTOCOL_ANY) instead of the actual protocol (e.g. SCARD_PROTOCOL_T0).

This should be fixed. Note that the severity of the bug seems to be low as arguably this output argument is ignored by a typical middleware application.

/cc @LudovicRousseau Thanks to @LudovicRousseau for reporting this.

Stop installing headers from our libraries into the common place

Currently, the build process is organized in a way that each sub-library (like //common/cpp) is built separately and then has its .lib+.h files installed into a common place (in the NaCl environment). Copying the headers is managed via a separate fake "headers_installed.stamp" file (which has a dependency on each of the shared .h file and therefore triggers re-installation once any of them changes).

Originally, that was introduced primarily because the NaCl SDK and naclports were using that model. This model allows, for example:

  • using a "stable" version of a library (the one that is already installed into the SDK) while developing a new version of the library;
  • deleting the library sources and temporary artifacts after building it once;
  • protection against accidental inclusion of the library's internal .h file.

None of those benefits really bring much in the context of sub-libraries within our project, and overall this approach causes a bunch of complexity and fragility in the build scripts. Examples of practical problems:

  • parallel builds might fail due to trying to install the headers simultaneously;
  • recreating the "env" would result in a stale state with compilation errors that the .h files cannot be found, unless all .stamp files are deleted.

Therefore the suggestion is to get rid of that model, and instead follow a simpler approach that all headers are included directly from the source tree.

Store logs across Connector app restarts-after-crashes

Currently, the "Export logs" button in the Connector app only exports the logs collected from this application execution.

As the Connector app (in Release mode) automatically restarts itself in case of a fatal error, the logs containing the crash reason are effectively lost.

We should probably store the logs in a storage before restarting the app.

The only currently possible workaround for losing the logs is to open the DevTools console for the Connector app's background page, and execute the following line of code:
GSC.Logging.getLogger('').setLevel(goog.log.Level.FINE);
This workaround effectively disables the restart-on-crash behavior, and allows to preserve and export the logs that were collected before the crash happened.

Implement support of chrome.certificateProvider.requestPin in the C++ client example

A new Chrome extensions API was added recently that provides a standard way to request PIN: http://crbug.com/612884 . Apart from providing a way to run a system-styled dialog, the API can be used in environments where otherwise UI is disallowed - e.g. the Chrome OS login screen.

We need to add support of this new API into the C++ client example that we provide, so that the middleware developers can adopt the new API faster.

Note that the required change is not just a trivial function renaming. The new API has more possibilities (e.g. showing an error message, keeping the dialog during PIN processing, repeating the request in the same dialog). And, what is more important, the API has a new requirement: a request ID from certificateProvider.SignRequest has to be passed when requesting a PIN (and this is the required parameter).

/cc @dskaram

Document the list of supported readers

Currently, we don't display the list of supported readers in the UI. This means almost zero troubleshooting possibility for the user (or an admin, a customer engineer, etc.) in case they experience some troubles. Also it means that it's hard to know whether a reader would work before buying it.

In fact, the CCID Free Software Driver that we use has a web page with a table of all supported readers: https://ccid.apdu.fr/ccid/section.html . However, the problem is that (1) this page is hard to discover, and (2) it corresponds to the latest version of the driver, meanwhile our Smart Card Connector app frequently has a few months old version of the driver (as we don't have a goal to update it immediately).

The request is to display this information in some form in the Smart Card Connector app's own UI, so that it's easily discoverable and free from versioning issues.

Display proper message when app is opened on non-Chrome OS operating systems

  1. Open connector on Windows/Mac/Linux Chrome.

Expected
Runs properly

Actual
?

We need to document the behavior on other platforms and show the proper signal to users. In the beginning we had blocked installation on other platforms but that got in the way of developers testing things out in their dev envrionments before publishing to the store (it's hard to develop on Chrome OS as middleware is a very low-level software that needs particular tools for development not found on Chrome OS).

Build initialization error: "ImportError: No module named pip._internal.cli.main"

Running env/initialize.sh in a clean repository results in an error - presumably, due to the incorrect handling of the PIP downgrade in webports or gclient or PIP itself:

________ running 'git -c core.deltaBaseCacheLimit=2g clone --no-checkout --progress https://chromium.googlesource.com/webports.git /ssd/smartcard/chromeos_smart_card_connector.N
EW/env/webports/_gclient_src_xtu6rh5k' in 'chromeos_smart_card_connector/env/webports'
Cloning into 'chromeos_smart_card_connector/env/webports/_gclient_src_xtu6rh5k'...
remote: Counting objects: 1, done79 MiB ...Counting objects: 1           
remote: Total 28005 (delta 22006), reused 28005 (delta 22006)        
Receiving objects: 100% (28005/28005), 36.79 MiB | 34.69 MiB/s, done.
Resolving deltas: 100% (22006/22006), done.
Syncing projects: 100% (4/4), done.                        
Running hooks: 100% ( 2/ 2) pip_install
________ running 'src/build_tools/pip_install.sh' in 'chromeos_smart_card_connector/env/webports'
Installing pip..
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python
 2.7 in January 2021. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Collecting pip
  Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB)
Collecting wheel
  Using cached wheel-0.34.2-py2.py3-none-any.whl (26 kB)
Installing collected packages: pip, wheel
Successfully installed pip-20.1.1 wheel-0.34.2
+ pip install --user pip==6.0.6
Traceback (most recent call last):
  File "chromeos_smart_card_connector/env/webports/src/out/pip/bin/pip", line 5, in <module>
    from pip._internal.cli.main import main
ImportError: No module named pip._internal.cli.main
+ pip install --user --no-compile -r requirements.txt
Traceback (most recent call last):
  File "chromeos_smart_card_connector/env/webports/src/out/pip/bin/pip", line 5, in <module>
    from pip._internal.cli.main import main
ImportError: No module named pip._internal.cli.main

libusb port: Support transfer timeouts

Currently, the transfer timeouts are handled like a transfer error.

This comes through a number of places in the code.
One example is the code that talks to chrome.usb: the chrome.usb API returns the error "Transfer timed out." in case of timeouts (just like any other error). We should do the string comparison there in order to distinguish the transfer timeouts from any other errors.

This is a very low-priority item, as it's not affecting any functionality in CCID or PC/SC-Lite (the CCID itself treats timeouts similarly to other errors).

Catch and abort illegal parallel PC/SC requests early

The PC/SC API requires that every thread of the application uses its own context:

Each thread of an application shall use its own SCARDCONTEXT, unless calling SCardCancel(), which MUST be called with the same context as the context used to call SCardGetStatusChange().

(https://pcsclite.apdu.fr/api/group__API.html#gaa1b8970169fd4883a6dc4a8f43f19b67)

Our implementation in the Smart Card Connector app retains this requirement. However, it's not currently enforced by the client-side libraries that we provide (neither JS nor C++ ones), which means that it can be violated without the developer being notified about that.

Practically, violating this requirement - e.g., sending a new PC/SC call before the previous one with the same hContext finished - can cause bad effects, like the calls being hung. Also - although not confirmed yet - it might lead to the hang of the Smart Card Connector app.

The proposal is to add debug assertions into our C++ and/or JS libraries that would catch these kinds of violations. Perhaps, crashing the caller is the only reasonable and effective measure in that case (note that typical clients would automatically restart after the crash, which hopefully will recover the state and let the user continue using the smart card).

As a stretch goal, we might want to investigate whether/why the Smart Card Connector app hangs for all clients in this scenario, and when that's the case try to fix that behavior.

How to figure out why a reader is not found

Hello,

tl;dr: My card reader is detected in ChromeOS but not Chrome on Fedora or Windows. I'd love some help on figuring out where to add debugging information, since the bridge between C and javascript goes a little over my head.

Context

I own a Gemalto PC Pinpad (reads: Ezio shield -- lsusb output) that I use with an OpenPGP Card (v2.x).

Under ChromiumOS (CloudReady) and I believe also ChromeOS v75 via a pixel slate the Smart Card Connector App is able to detect and connnect to my device (even sending some sample pcsc commands, and ccid commands).

Unfortunately it's not quite detected under Fedora or Windows with Chrome/Chromium using the same extension. The reader works with both pcscd and gpg/scdaemon in this environment normally.

What I've tried/found

Following Troubleshooting Apps under desktop OSes I killed pcscd and checked the permissions on the device and setup some udev rules:

[travis@travis ~]$ ls /dev/bus/usb/001/016 -l
crw-rw-rw-. 1 root root 189, 15 Jul 30 08:19 /dev/bus/usb/001/016
[travis@travis ~]$ ls /dev/bus/usb/001/016 -lZ
crw-rw-rw-. 1 root root system_u:object_r:usb_device_t:s0 189, 15 Jul 30 08:19 /dev/bus/usb/001/016
[travis@travis ~]$ ps aux | grep pcscd
travis   24930  0.0  0.0   5992   828 pts/1    S+   08:24   0:00 grep --color=auto pcscd
[travis@travis ~]$

still with no luck.

background.js shows the reader is found by libusb:

 [  0.061s] [GoogleSmartCard.Libusb.ChromeUsbBackend] 1 USB device(s) available: [{"device": 0x00, "manufacturerName": "Gemalto", "productId": 0x000034C2, "productName": "Ezio Shield", "serialNumber": "R145023804255", "vendorId": 0x000008E6, "version": 0x00000102}]

But later window.js will remind us that there's no hope here:

[  0.012s] [GoogleSmartCard.ConnectorApp.MainWindow] Displaying 0 card reader(s): []

I've rebuilt the app with export CONFIG=Debug and I don't think I was seeing any more log messages, so I also ran find smart_card_connector_app -exec sed -i 's/logger.fine/logger.info/g' {} \; for good measure. There's definitely more logging now but pretty much only helpful for Known Apps.

Note that neither ChromeOS or GNU/Linux have the device appear in the "Add Device" window, because that searches exclusively for 0x0B interface-class smart card readers, which approximately 5% of readers are not, but the ReaderTracker list seems to be getting populated from elsewhere, and seems sufficient for the usecase. (I did window.readerTracker = readerTracker somewhere and tried playing around with debugging that way to no avail. Both the "successful" and "unsuccessful" readers are empty)

I'm not quite sure how to debug further, I'd love some suggestions on where I could add logging to help narrow down why my reader works in one environment but not the other.

Sending a message with unexpected type raises a fatal error in the Connector App

Currently, a fatal failure happens when a message with unhandled type is received in the Connector App.

Given that the fatal failure makes the whole Connector App to "crash" and restart when in Release mode, this is not an acceptable behavior.

Instead, a warning/error message should be emitted, and the message channel to the bad client should be destroyed.

/cc @dskaram

"Card absent or mute" errors when ejecting and reinserting a card

There seems to be some currently not well understood combination of conditions that leads to the CCID driver being unable to power up the card and, consequently, to failures to perform any SCard operations with it.
One scenario that seems to cause this issue relatively often is ejecting a card and reinserting it back within 2-3 seconds; however, the same problem was observed in other scenarios as well.
It's also unclear whether it's related to specific reader(s) or card(s); so far it was reproduced on two different readers ("SCM Microsystems Inc. SCR 3310" and "Gemalto IDBridge CT30") and on one specific card ("Oberthur Cosmo (eID)"). It was reproduced on two different versions of the CCID Free Software driver: 1.4.33 and 1.4.31.

In the logs, the problem manifests itself through the following errors:
CmdPowerOn Card absent or mute
IFDHPowerICC() PowerUp failed

Blocking PC/SC calls are not terminated when the client is disconnected

There's a problem with the Connector app that it doesn't free the handles obtained by a client when it's terminated during a blocking PC/SC call (e.g. the potentially infinitely working SCardGetStatusChange function).

One of the effects is that a terminated and then quickly restarted client may be blocked for considerable amount of time or even forever if it was using blocking PC/SC calls.

The probable reason for the bug is that our PC/SC-Lite port doesn't seem to contain the code that would terminate blocking PC/SC calls when the client disconnection event is received. The cleanup of the client's handles seems to be is effectively postponed until the last blocking call from that client is finished, which is wrong.

/cc @dskaram

Introduce a better protocol for single-message-based communication between Connector app and the client apps

The existing protocol has several issues, mainly:

  • Client restart handling is bad. Connector app may start processing the commands from the restarted app in the same environment as it was before the restart, but then, after some time, it will realize that the client app has been restarted - and it will clean up and destroy all handles and start with a clean environment after this point - which really puts the client into a weird state. The commit 215d5ba has a temporary workaround for this, allowing the client to wait until the full "handshake" finishes before sending the commands.
  • The timeouts for sending ping messages and for considering the Connector app as dead have to be hardcoded based on the sources of the Connector app.
  • There's no way in the protocol to send a generic error from the Connector app to the client (like "permission denied" or "received message has invalid format").
  • Asymmetry between "ping" requests and "pong" responses is a complication that brings not many benefits.

Auto-generate Connector app's manifest.json from CCID config file

Currently, the Connector app's manifest.json has to be updated manually with each update of the CCID driver, because the "usbDevices" key in the manifest has to contain exactly the list of devices supported by CCID.

Most of the functionality is, however, already automatized: the Makefile of the CCID NaCl port produces the file app_manifest_usb_devices.json which contains exactly the text that has to be inserted into manifest.json.

The only missing piece is auto-generation of manifest.json from a template with a placeholder for the app_manifest_usb_devices.json file contents.

UI "add reader" button looks confusing

Two things that, according to feedback from users, are confusing in our UI:

  1. The "add reader" button may be misinterpreted as an invitation for users to click on it. However, users actually don't need to click it if their reader is already displayed (which should happen for 99% of users).

  2. After clicking "add reader", the UI says "No compatible devices found" even when there's a connected smart card reader that was already added before. This confuses as the users may think that their reader isn't recognized.

Fix the C++ client example to start listening for certificateProvider events before the NaCl module is loaded

Currently, the provided C++ client example implementation starts listening for chrome.certificateProvider events only after the NaCl module has been loaded.

As the loading of the NaCl module may take a considerable time (several seconds or even dozens of seconds), this means that user may not be able to start opening HTTPS-with-client-auth websites for quite some time (all such attempts would finish in HTTPS error in Chrome).

So this should be improved, by setting up the required listeners straight at the app startup code. The requests, that come before the NaCl module has finished loading, should be stored somewhere and delayed.

/cc @dskaram

Get rid of relying on pre-set env variables in build scripts

Currently, one has to run "source env/activate" before being able to compile the code, otherwise the Make will fail with unclear errors (like complaining about the NACL_SDK_ROOT directory).

We should probably get rid of that and change our Makefile's to do this automatically, since the current situation is confusing for developers. Historically, this was done in accordance to the standard Native Client development practice, allowing to reuse an SDK between multiple projects or switch between different SDK versions, but in the light of NaCl deprecation this isn't useful anymore.

Display list of connected clients in Connector App's UI

Currently, the Connector app's window does not display the list of all currently connected clients. This makes it non-opaque for the end users (as it's not clear which client apps may operate with the smart cards currently), and complicates investigations of issues (tricky to understand where is the problem cause: in the Connector app or in the client).

Connector app's window should display the names of all connected clients. (Probably - with links to WebStore).

/cc @dskaram

Failed readers can be displayed on top of successfully recognized readers

The Smart Card Connector app's window doesn't currently sort the displayed readers by any criteria except the internal identifier.
This may lead to users confusion. For instance, in the case of a composite device which CCID driver recognizes as several "readers", and the first couple of them aren't actually readers - then their failed items can displace the item that corresponds to the actual reader (it may become invisible unless the user notices the scrollbar and scrolls it). Real-world example of such device - YubiKey 4.

We should display the successfully initialized readers first, and the failed readers - only after them.

After this is fixed, we should also consider, as a future improvement, hiding these not-actually-a-reader items.

/cc @dskaram

Fix potential data race in the PC/SC-based reader tracker

We have the functionality that tracks the list of currently available smart card readers based on the information exposed by the PC/SC API.
This implementation has a potential data race that it can miss the changes if they happen between the completion of one PC/SC call and the beginning of the next one. In that case, the change would only be recognized after some time (60 seconds at worst with the current implementation). This bug tracks the fix of this data race.

After this data race gets fixed, we could actually make a small performance improvement by avoiding the need to make a periodic PC/SC call (every 60 seconds currently) from that code.

CERTIFICATE_VERIFY_FAILED when running initialize.sh

The env/initialize.sh script is currently broken:

third_party.fancy_urllib.InvalidCertificateException: Host storage.googleapis.com returned an invalid certificate ([SSL: CERTIFICATE_VERIFY_FAILED] cer
tificate verify failed (_ssl.c:727))

The problem seems to be with the CA certificates validation in the current version of the NaCl SDK.

Display the statuses of the smart card readers in the Connector app window

Currently, the Connector app just displays the list of all visible readers without any hints whether a reader is available or not.
This is fine when everything works smoothly, but when there's some problem with the connected reader, understanding what's going on becomes pretty tricky. Even when the driver failed to initialize with a reader, it would be still displayed in the usual way. This means poor UX and misleading when investigating some problems.

So the task aims are:

  1. (required) Provide UI feedback on each reader, so that it's clear for the user which devices are ready to use and which are (for any reason) failed.
  2. (optional) Provide a reasonable UI feedback while the reader is in the process of being initialized.
  3. (optional) In case of failures, display also the error messages.
  4. (optional) Provide UI feedback for each reader when an actual data is transferred to/from the device.

/cc @dskaram

Add admin setting to suppress auto-launching the Connector App window on initial start

Today, even when the Connector App is force-installed via Chrome admin policy, the App's main window is automatically launched. This may be confusing for the users - basically they don't understand what this app is for and what they should do.

Unfortunately, there's no Chrome API that allows the App to know whether it was force-installed or installed manually.

Therefore the suggestion is to add an admin setting that would allow the admin to configure the forced disabling of the window auto-launching.

/cc @dskaram

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.