I am trying to do Web-extension to Mozilla, which will use pkcs11 to sign, encrypt or verify document, mail.
I am using this api to comunicate with my eid cards and get slots from them.
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/pkcs11
Is it somehow possible to OpenSession with this slots in WebExtension plugin?
Because this pkcs11 seems like have not supported it yet.
I would like to call some function like C_OpenSession and then C_Login.
Thanks for help
The only purpose of PKCS#11 javascript API in Mozilla nowadays is to register and unregister PKCS#11 libraries available to Firefox. It's even stated in the documentation:
The pkcs11 API enables an extension to enumerate PKCS #11 security modules, and to make them accessible to the browser as sources of keys and certificates.
Firefox uses registered PKCS#11 libraries to access client SSL certificates. AFAIK there is no public javascript API that would allow you to call other PKCS#11 functions (such as C_OpenSession or C_Login) provided by these modules.
There used to be window.crypto.signText API available for easy signature creation but Mozilla killed it in Firefox 33. They didn't see it as a big deal because PKCS#11 signing could be implemented with extension and they provided signTextJS extension as a proof. Sadly Mozilla killed it in Firefox 57 when they migrated to WebExtensions and removed support for XPCOM-based add-ons.
If you want to use PKCS#11 API from Firefox nowadays then you need to use/create extension which will spawn local process and communicate with it via native messaging or you'll need to use/create application which will spawn local web server and communicate with it via web requests or web sockets.
Related
There was a File System API but shown as deprecated now: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestFileSystem
There is now another, File System Access API: https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API
What happened to the old API and why was it discontinued? Should the new File System Access API be stable in all common browsers?
It turned out that File System Access API is not deprecated, it's just not standardised (May 2021); the deprecated one is the function window.requestFileSystem; the same function on Chromium-based browsers is window.webkitRequestFileSystem.
File System API is for creating a virtual drive (temporary or persistent) for each website when using browser-based db (IndexedDB) is not necessary especially for the purpose of storing files.
https://developer.mozilla.org/en-US/docs/Web/API/FileSystem
File System Access API is different, it is for accessing the real file system of the OS. This API is now standardised and available on Chromium-based browsers (May 2021). Firefox has not yet adapted this API.
https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API
Status of these APIs: https://developer.mozilla.org/en-US/docs/Web/API
I currently have source code for a Chrome App, but as the platform is being deprecated I need to migrate my API to a Progressive Web Application.
As I still want support for USB in my web platform application, it was suggested that I use the Web USB API to retain functionality, but I can't seem to figure out the equivalent's for the following and how to implement them:
chrome.usb.releaseInterface()
chrome.usb.closeDevice()
chrome.usb.claimInterface()
chrome.usb.findDevices()
chrome.usb.bulkTransfer()
(Also, I also found there is a USB Library for Node.JS that works similarly also; is this a good alternative too?)
The WebUSB API provides a USBDevice interface which is returned by navigator.usb.getDevices() and navigator.usb.requestDevice(). This interface has methods equivalent to all but one of those listed above:
chrome.usb.releaseInterface() -> releaseInterface()
chrome.usb.closeDevice() -> close()
chrome.usb.claimInterface() -> claimInterface()
chrome.usb.bulkTransfer() -> transferIn() or transferOut().
chrome.usb.findDevices() is more complex to replace and first requires explaining the differences between the permission model for the WebUSB API and the chrome.usb API. The WebUSB API does not provide an install-time permission to access USB devices. A site must call navigator.usb.requestDevice() to ask the user for permission to access new USB devices. For devices with serial numbers permissions are remembered and so you can call navigator.usb.getDevices() to get a list of currently connected devices a site previously got permission to access. This is the same model as the chrome.usb.getUserSelectedDevices() function. The chrome.usb.findDevices() function also implicitly opened the devices in the process of returning them to the application. There is no equivalent to this behavior. The site must explicitly call open() on the USBDevice interfaces returned by these methods.
Note, that if this application is being deployed into a managed environment the WebUsbAllowDevicesForUrls policy can be used to mimic the Chrome Apps permission model. Devices allowed by policy will be returned by navigator.usb.getDevices() without the need to call navigator.usb.requestDevice() and prompt the user first.
So, till Windows 7 there was a Microsoft ActiveX component: CAPICOM, which one could call from Javascript and then show the contents of the certificate storage on the client's machine. The client then could choose the appropriate certificate and sign some document with the certificate's private key.
That's how the access to the certificate storage looked in Javascript:
var MyStore = new ActiveXObject("CAPICOM.Store");
var oCertificates = new ActiveXObject("CAPICOM.Certificates");
// attempt to open the personal certificate store
MyStore.Open(CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY);
What’s the alternative to using CAPICOM nowadays? I want the client to be able to sign some piece of text with his private key in the browser and then send the signed text with the public key to the server. Is it still possible?
Maybe I could use Java or Silverlight instead of pure JavaScript? What about PKI.js and similar?
In general, currently is not possible due to lack of support of browsers to Java or silverlight.
Chrome has dropped support to NPAPI plugins. Firefox has announced it will discontinue it in 2017, Edge has no support. Microsoft has deprecated Silverlight and Oracle has also announced the deprecation of the Java browser plug-in. Only old versions of IE could be used.
Javascript cryptographic libraries such as PKI.js, forge or the built-in WebCryptographyApi can be used to perform digital signatures, but they do not have access to the Operative System KeyStore, so you can not access to the installed certificates
Alternatives (Not very encouraging):
Use WebCryptographyApi loading certificates in browser (not for smartcards)
Launch a local application installed on your device and invoke via protocol, using an embedded http server or with chrome messaging api
Wait patiently to Key Discovery Api which will provide with access to the OS keystore to WebCrypto
In fact I've created a .NET ActiveX object and used X509Certificate2UI class and others from the same namespace to show information about the certificates and to sign some data.
Pros: no need to use CAPICOM.
Cons: it's still an ActiveX component and so it's available in Internet Explorer only.
But that was ok for my client so I took this path.
I have tried looking for methods to communicate . For instance, Mozilla provides XPconnect for bindings between Javascript to XPCOM. Does Chrome have any such APIs?
As Gael mentions, Native Messaging is your nearly only way.
You need to write (and distribute separately) a Native Host module for the extension - that Chrome can launch and pass your data to. It will serve as a proxy between your extension and COM.
You could also make a service that exposes a local web or WebSockets interface that the extension can call. This way, you don't need Native Messaging, but it makes for some security concerns.
In either case, you need an external "proxy" (or "glue", if you prefer that metaphor) software.
I'm working on a ELB monitoring application that I'd like to build with JS and host directly in S3. I have no experience of JS and I'm struggling to get to grips with CORS.
I have successfully created a build of the SDK for my browser (http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-building.html) which includes ELB API support.
I have integrated Amazon login (http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-configuring-wif.html) with my script and I have attached it to an IAM WebIdentity role.
When I call
elb.describeInstanceHealth(elbRequestParams).on('success', describeInstanceHealthCallback).send();
I get an error in Javascript console
XMLHttpRequest cannot load 'elasticloadbalancing.eu-west-1.amazonaws.com/'. The request was redirected to 'aws.amazon.com/elasticloadbalancing', which is disallowed for cross-origin requests that require preflight.
I can't find any clear documentation that what I'm trying to do won't work, but, I'll admit I'm confused by some of the terms in the documentation and I have no experience of CORS in previous applications to fall back on. I would think the whole JS-SDK for the browser is a bit redundant if the majority of services aren't CORS aware and need to be.
I can get this working by disabling web-security in my Chrome browser, obviously this isn't a good workaround but would indicate to me that CORS is the issue.
Is anyone familiar with this approach, is it a problem that I'm hosting on S3, or, would I have this problem from any server? Should I be configuring my S3 bucket with CORS, or, is it that there's no CORS policy on the 'elasticloadbalancing.eu-west-1.amazonaws.com' endpoint?
Thanks
Andrew
I have successfully created a build of the SDK for my browser (http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-building.html) which includes ELB API support.
The referenced page already provides the first clue towards the lack of CORS support for elasticloadbalancing.eu-west-1.amazonaws.com you correctly suspect to be the cause here:
If you are working with the SDK outside of an environment that
enforces CORS in your browser and want access to the full gamut of
services provided by the AWS SDK for JavaScript, it is possible to
build a custom copy of the SDK locally by cloning the repository and
running the same build tools used to generate the default hosted
version of the SDK.
That is, the main reason for the official AWS SDK for JavaScript in the Browser excluding all but the currently 5 services listed in section Supported Services within Working with Services in the Browser is their lack of CORS support:
It is possible to use the SDK with other services if CORS
security checking is disabled in your environment. In this case, you
can build your own custom version of the SDK. See the Building the
SDK section of the guide for more information on how to create a
custom build of the SDK.
Unfortunately neither Amazon EC2 nor Elastic Load Balancing currently offers CORS support, see e.g. this recent Feature Request (CORS support for EC2 service), where the author rightfully reaches the same conclusion as you did already (while also hinting on Node.js to be another major use case, which supports all available AWS services, see Working with Services in Node.js):
From my point of view if AWS is providing a aws-sdk-js library all AWS services supported by this library should support CORS so that the aws-sdk-js iibrary is not just useable in a node.js environment but also in a browser.
While I agree in principle and would have expected faster turnaround times on this myself, AWS is well known for an agile approach to product development, i.e. start early with a small feature set and improve over time based on customer feedback. Notably the SDK is labeled Developer Preview only, i.e. not even BETA yet and I'd hope this to be addressed in the future accordingly - admittedly this is easily overlooked and a more prominent warning might go a long way in sparing users the time to figure out this limitation by themselves.