View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0001417||Main CAcert Website||certificate issuing||public||2016-10-03 17:31||2022-07-28 17:07|
|Platform||PC Windows 10, IE11 Chrome Firef||OS||Windows 10 Pro 64bit, Ubuntu||OS Version||Current|
|Product Version||2015 Q3|
|Summary||0001417: Unable to generate client certificate|
|Description||Unable to generate client certificate|
Clicking generate keypair in browser results in the error
"I didn't receive a valid Certificate Request, please try a different browser."
This happens in IE11, Edge, Chrome current version, and Firefox current version.
|Steps To Reproduce||log in to cacert.org|
click client certificate
check off wanted email address
click agree to terms
click generate keypair within browser
Immediately receive error "I didn't receive a valid Certificate Request, please try a different browser."
Same error occurs in IE11 Edge Chrome and Firefox
|Additional Information||CACerts.org is added as trusted site|
TLS and SSL are enabled
Tested running Trusted Sites on low security setting in IE
Tried on both 32 and 64 bit versions of all broswers
|Tags||browser, certificates, html|
The same bug happend to me to with
- Chromium 55 on Ubuntu 16.04
- Vivaldi 1.6 64 Bit on Ubuntu 16.04
- Edge on Windows 10
But I could create a new certificate with
- Firefox 50.1 on Ubuntu 16.04
Some other checks to create new certificates:
it does NOT work with
- Edge 38 on Windows 10
- Opera 42 on Windows 10
- Vivaldi 1.4 on Windows 10
it works still with
- Firefox 48.0 on Windows 10
I filed a bug at Chromium and at Vivaldi a few days ago. Following the answer from Chromium:
Issue 799246 in chromium: Cannot create a certificate with cacert.org
Von: asa… via monorail
Comment 0000003 on issue 799246 by email@example.com: Cannot create a certificate with cacert.org
This site is using the <keygen> element to generate a keypair. This feature is deprecated. See https://www.chromestatus.com/features/5716060992962560
Screen Shot 2018-01-05 at 4.44.07 PM.png 22.1 KB
You received this message because:
1. You reported this issue
"Since Chrome 49, <keygen>'s default behaviour has been to return the empty string, unless a permission was granted to this page. Removed in Chrome 57."
"IE/Edge do not support <keygen> and have not indicated public signals to support <keygen>. Firefox already gates <keygen> behind a user gesture, but is publicly supportive of removing it. Safari ships <keygen> and has not expressed public views regarding its continued support."
Further information at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen
This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Avoid using it and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time."
Alternatives to <keygen>:
Other discussions about alternatives:
Generating keys still works for me with
Firefox 57.0.4 (64-Bit, Linux) installed in openSUSE Leap 42.3.
On Fri, 2 Feb 2018 10:29:41 +1100, Peter Yuill <peter AT NO SPAM c.o.> wrote at CAcert Board List:
I went through the process of generating keys and CSR in openssl then
submitting CSR through the advanced section of “New Certificate” and it
worked perfectly for me (using current Firefox). I have to say it is not a
simple solution and it certainly requires a much higher level of technical
skill than the browser solution, but it does work.
I did some research on possible tools to simplify the process and I have a
proposal. As far as I can see the browser route is dead, so we need to look
elsewhere. I am looking at the possibility of a desktop app that would
generate keys and CSR then connect to the cacert.org <http://cacert.org/>
site through a screen scrape library to submit the CSR and store the
certificate back in a local keystone. The one extra step required is to
import the certificate into browsers/mail clients, which should not be
difficult for most people. I am starting work on a cross-platform proof of
concept which I hope to be able to demonstrate in a few weeks.
"The browser route is dead" - indeed, so solutions running natively on the platforms are necessary.
A technical discussion thread was started here:
Supporting many platforms can be challenging. Because a simple solution is better than none, I'd prefer to have console-based scripts using on-board tools such as openssl (usually available for UNIX-style systems) or certreq (on standard Windows since many years - Vista?) as a baseline. Automating the CAcert certificate request page is not essential for the simple tool variant, where a graphical, more powerful and comfortable variant can complement it and doesn't need to cover platforms on an equal level or have the same robustness.
For UNIX-style systems I created a shell/openssl based solution as proof-of-concept here:
http://70t.de/download/ , file with pattern cacert_client_certificate_<date>.tar.xz (at time of writing cacert_client_certificate_2018-04-11.tar.xz )
Read more on cacert-devel starting here
I tried out cacert_client_certificate_2018-04-09.tar.xz. Thanks for creating it. I have a few suggestions/remarks about it.
Multiple inputs of a passphrase are required:
1. Unlock the key (from the file generated in the first task)
2. Set a passphrase for the new certifcate file
3. Repeat (confirm) the passphrase from 2. above
Input area (sequence of 3 passphrases): [1. Unlock key password]
Enter Export Password: [2. passphrase for new cert]
Verifying - Enter Export Password: [3. repeat 0000002]
The three numbered items should be explicitly numbered and named in each of the prompts that come after. The first prompt of "Input area (sequence of 3 passphrases): " does not indicate that you are supposed to type on the "passphrase to protect the generated key" when generating the RSA private/public key pair.
If ready, press enter to open the certificate with the browser for import.
In the case of Firefox 59.0.2 (64-bit), Ubuntu 16.04.4,
a dialog box will ask
What should Firefox do with this file?
(*) Open with [View file (default]
( ) Save File
[ ] Do this automatically for files like this from now on.
Questions about passphrase and labels eventually displays
the certificate details but is not imported. I had to go to Firefox's Certificate Manager and
manually [Import...] the newly created new_certificate_$USER.pfx file.
You will need to unlock the .pfx file with the
"Enter Export Password: [2. passphrase for new cert]" from above.
||Oops. That note should have gone to the mailing list where cacert_client_certificate_2018-04-09.tar.xz was posted. There is no edit/delete.|
It is nearly three years since this issue was raised. Has there been no viable alternative process found for generating client certificates without the deprecated keygen tag?
Would it be possible for someone to write a HowTo guide for manually performing the process on the command line using OpenSSL and putting a corresponding CSR submission form on the website for the server side part of the process.
Could something like this be used?
Here is an example that uses that code:
Here's another option:
As a reply to https://bugs.cacert.org/view.php?id=1417#c5828 there indeed is a workaround for this problem.
If you click the "show advanced options" checkbox you can provide a manually created CSR, which makes the keygen tag obsolete. But the process in not really easy or user friendly. See https://wiki.cacert.org/FAQ/CSR as a starting point if you want to try that way.
I had a (very short!) look at the proposals of BarryN.
https://www.php.net/manual/en/function.openssl-csr-new.php will probably not help us, because this is code that runs on the server. It would not be appropriate for our standards to create a keypair on the server and then send it to the browser, because of the additional risk of compromising the key on the server or during transfer. BTW, this is the reason why CSRs have been invented.
https://pkijs.org/ looks more promising to me. As the provided example shows, the library seems to be able to create a keypair and a corresponding CSR locally in the Browser. If the library uses the key storage of the browser for key generation and therefor does not have access to the private key itself, this may be a valid replacement of the keygen tag, since this is exactly what the tag does.
But, first of all, this assumtion has to be verified by a code review. If the library creates the private key "itself", therefor having access to it, this also imposes the risk that the private key is compromised during the creation process.
Another downer is the sentence "Safari, Edge, and IE do not have complete, or correct implementations of Web Crypto.", which once again leaves a significant portion of the browser market uncovered...
Nevertheless, if there's anyone who would like to give it a try it may be worth to do more research in this direction.
||The 'downer sentence' was from 2015. Almost all browsers are supported now. To see what is and isn't supported visit https://caniuse.com/#feat=cryptography|
||I thought the java script solution might be the better one. I have tested a few browsers and the basic functionality seems to work. According to the chart the current version of IE, Edge, Chrome, Firefox and Safari all have at least basic support.|
From a mail on the Support mailing list:
seht Euch mal die Library PKI.js an. Das ist ein Werkzeugkasten in
im Browser erzeugen:
* PKCS#10 CSR
* PKCS#12 File
Das PKCS#12 File muss der User dann nur noch in den Browser importieren.
PKI.js kann deutlich mehr, als das alte <keygen>, damit kann man z.B.
auch EC Keys erzeugen.
What's the state of play?
What happened to the app from Peter Y?
What happened to the proof of concept from dops?
What about pkijs.org?
What happened to the Java Script solution?
What about the library PKI.js?
As a technical layman, I do not really understand it. The approaches sounded promising. Were they pursued further?
||same here as L10N here and hoping some type of solution would be soon proposed.|
Looking into https://pkijs.org/ once more.
It seems possible to create a web page which could replace the key creation with openssl where openssl is not readily available (like on Windows):
- Create a key pair with the generateKey API
- Create a PKCS10 CSR with a user provided data for CommonName and SubjectAltName using the CertificationRequest class of PKIJS
- Show the PEM encoded request to the user for Copy/Paste
- The user must then paste the CSR into the CAcert web page, and use Copy/Paste to copy the created certificate into the PKIJS-based website
- The PKIJS based website combines key and certificate in a PKCS#12 (*.pfx) structure which can be downloaded by the user
This PKCS#12 structure can be imported into Mozilla's certificate database or into the windows certificate storage.
Of course this also has the potential to be integrated in the CAcert web page, which could eliminate the Copy/Paste operations, but I'd consider that as the second step.
The main problem I see is that the creating script knows the created private key and could easily compromise it (intentionally or unintentionally). This is essentially the same as in an openssl based script, but since the script is loaded on demand from some webserver, as well as several libraries, the potential of fishing-like abuse is IMHO considerably greater...
Nevertheless it could be an easier-to-use variant for Windows users.
Regarding download: Search engines present solutions for locally creating files for "download". The first link looks like a clean and modern solution, which is also later mentioned behind the 2nd link with a longer history:
So should be promising that all private key related operations can be done locally in the browser.
I've tried a "proof of concept" implementation at https://secure.convey.de/publish/ted/TestPKI.html
The PKCS#12 file created there can be parsed by OpenSSL, but neither the Windows Certificate Storage nor Thunderbird/Firefox are able to use it for import... :-(
Probably there's still some research necessary about the details of PKCS#12 creation...
I could import PKCS#12 files created by this PoC project successfully in Firefox and the GNOME keystore (Seahorse).
My code should be verifiably correct according to outside sources. It should work Everywhere.
So try: https://tecreations.ca/java/downloads/release/SecurityTool_User
So that would be: org.cacert.SecurityTool_User IF you understand Java.
Launch it, try, see what happens.
So Far, CACert, doesn't recognize or won't accept, a CSR. The Key has nothing to do with it.
CSR == CERT. Yes/No? What do you think?
If they can sign, if not, I can.
They'd have to 3rd party, accepted 3rd Party Signature.
So, If you need, I will. Accept, Verify, Sign.
All data reference points.
Special Identifiers, #codeSigning, #clientAuth, #serverAuth, #SSO, if you want.
Ok, hang on, will post when tested: Copy/Paste Link:
GenerateKey, Copy CSR, View Clipboard.
Oh, there's some kind of problem....
I'll try to repost when I have an answer.
You should be able to:
Unpack to <User.Home>restarted-1\....
Generate Key, Copy CSR, View Clipboard....
It doesn't really matter, CA Cert Won't Sign. I can sign, but do you trust me???
I mean c'mon, get real.
You may generate valid PEM CSR by using tecreations.ca/java/downloads/release/signed-cacert.org.jar
And Then Clicking "Generate Key", this will create a new private key.
Click "Get CSR" that will copy the CSR to the clipboard, based on your current DistinguishedName parameters. This is to identify you apart from everyone else.
Click "View Clipboard": This should show your current selection, ie, your CSR.
This is what you should paste to CACert.
It currently is NOT WORKING CORRECTLY.
Options are available to VERIFY YOUR SITUATION.
I got your proof of concept from 0001417:0005921 running on windows, with some troubles, only to find out that this was probably not necessary at all. ;-)
What I found out matches quite well with your flow diagram, so I guess I got the right idea... I can confirm that the created PKCS#12 files can be imported into the windows certificate storage. Probably the details of the DN in the CSR have to be polished a bit, but as a proof of concept this is indeed quite good.
Concerning integration of the backend into the existing infrastruction, I'd propose to install the backend service on the CAcert webserver, so it can have access to the main database, and maybe the filesystem.
In this setup the backend can, after verifying the user's password or certificate, write the CSR into the "right" database table (DomainCerts for server certs or EmailCerts for client certs). So it will be sent to the signer, who in turn stores the created certificate in the database. Then the backend can read the cert from the database and return it to the browser, where the frontend can continue to create the PKCS#12 file.
From my gut feeling I'd advise against using a web socket connection to push the "certificate ready" notification to the browser. It is much easier for the user to evaluate (with the browser's network analysis tool) what's going on, and which data is sent to CAcert, if only POST and GET are used. So this should make it easier to review the process and get confidence that indeed no private keys or other private things are sent to the server. ==> The browser should poll in intervals to check if the certificate is already available. Note that the backend might even give some hint on the "expected time of arrival", based on the number of open requests in the signer's queue...
Apache itself might be configured use rewrite to forward requests for a specific path to the backend, so the backend might be accessible by something like https://www.cacert.org/certapi/...
This way we could probably create a very quick and clean integration of your PoC into the existing infrastructure, without writing a single line of PHP code. The certificates created with the backend would show up normally in the user's account page and could be managed, revoked and renewed using the existing user interface. On the other hand, if we decide that the backend has any problems we could easily turn off the whole thing by removing the rewrite rule, and everything would be as before.
And, as a bonus, the backend may be the foundation for full grown support of the ACME protocol, to completely automate issuing of server certificates, like it is provided by let's encrypt. So you might notice that I really like this! :-)
The main problem I have is, that currently I have no idea on who could review the backend. I had no contact with Go yet, so at the moment I cannot do reviews in good consciousness. I don't know about Dirk (or maybe Gero), but I've not yet heard them talking about Go... Nevertheless I'd propose to implement the backend on the testserver as soon as possible. While it usually needs some time, learning a new programming language is not something completely new to me ...
||NOTE: Your chart is valid, till the browser used is capable to create a CSR. AFAIK only the Basilisk, Palemoon, and Seamonkey browsers are able to do it nowadays (2021-06). Did you mean to use some plug-in module(s)?|
I attach an updated sequence diagram (+ PlantUML source) that has numbered steps and more details.
After step 014 the signer client will attempt to get the certificate signed. On success it will be written to the database and returned in step 018.
If the API endpoint is separated from the regular PHP application we need a way to identify the user in step 013 to be able to validate the certificate request. A possible solution could be a random token (similar to a CSRF token) that is sent to the user in step 006, stored in the database and sent in step 013 (i.e. as Bearer token in an Authorization header).
certificate-creation-sequence-2.png (75,271 bytes)
certificate-creation-sequence-2.png (75,271 bytes)
certificate-creation-sequence.txt (1,571 bytes)
certificate-creation-sequence.txt (1,571 bytes)
||We could use signed (HMAC) JWTs for authentication and would not need to store the token in the database then (in step 006). There are PHP libraries for creating JWTs and there are Go libraries for parsing and validating JWTs. A validity period for the JWT could be calculated from the issue timestamp (JWT payload field "iat").|
||@jandd my knowledge gaps filled, One question: Private keys are encrypted in PKCS#12. You use the password from Step 9 to encrypt PK in PKCS at Step 22, right? - I can also offer testing on about 5-7 more browsers under Windows 10 and Linux Ubuntu, if you need it.|
I found the setup of the backend a bit tricky, so I'd really love to set it up on the testserver. That way it would be easy to let loose the whole zoo of browsers on the code.
First step: Setup as is, on its own TCP port, with its own CA keys and OpenSSL creating the certificates
The next steps would then be integration into the web page and access to the database to create certs with the (test-)signer...
@jandd, is the current testserver enough up to date to install all the necessary dependencies (Node.js, Go, whatever else is missing)? Should I try to do the installation or will you do it yourself? We'll need an additional TCP port in the firewall, I guess that's something you must do yourself anyway?
The test server is running Debian 8.11 (which is EOL), the nodejs version in Debian 8 is ancient (0.10.29~dfsg-2) as is the go version (1.3.3-1+deb8u2).
I think it would be better to have a separate container to build the actual release packages/binaries and only use the compiled result on the test server. Maybe we could do this on https://jenkins.cacert.org/ as we do for other Go builds.
We need a proper deployment process for other reasons so this might be a good reason to start developing it :-)
Here is a small example for generating a valid JWT for a user in PHP (can be checked via https://jwt.io/):
<?php require 'vendor/autoload.php'; use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; $configuration = Configuration::forSymmetricSigner( new Sha256(), InMemory::base64Encoded('qRxCOLBj+12J+gDvVLOOBJv7xvyKt1nV1KadkjeGcn8=') ); $now = new DateTimeImmutable(); $token = $configuration->builder() ->issuedby('https://www.cacert.org') ->permittedFor('https://certapi.cacert.org') ->issuedAt($now) ->canOnlyBeUsedAfter($now->modify('+15 minute')) ->withClaim('uid', 'db952e7f-4393-4ecd-9673-207d061e212e') ->getToken($configuration->signer(), $configuration->signingKey());
all variables that are hardcoded in the example should come from configuration or the database (in case of the uid claim).
I successfully checked the code in a Debian 8 Docker container to see if it will work with PHP 5.
We still have the "new" testsystem at test3.cacert.org. Maybe we update that to a recent Debian version and try to get the PHP code of the main website running there? Or just use it for the backend and indeed add some (PHP?) api to the "old" testsystem?
I agree to developing a deployment process, but hopefully that should not block testing/developing for too long...
@alkas yes the private key is encrypted in https://git.dittberner.info/jan/browser_csr_generation/src/branch/master/src/index.html#L150 (it uses 3DES because AES is not supported properly in many Applications/Systems yet). I agree with @Ted that we should have a deployment on the test server, because a local setup requires a lot of developer tooling.
The new testsystem (test3) uses PHP 7. Our PHP code base is not compatible with that without merging at least https://github.com/CAcertOrg/cacert-devel/pull/21 into an integration branch and testing it extensively.
If we choose to go the PHP 7 route we should put our main activities there. This would also allow us to upgrade the production system to a supported OS.
Should I go the PHP 7 route first or should I start with a proposal for the deployment automation?
||My proof of concept implementation from https://bugs.cacert.org/view.php?id=1417#c5921 is now available at https://code.cacert.org/jandd/poc-browser-csr-generation|
|2016-10-03 17:31||Wiesshund||New Issue|
|2016-12-24 19:29||L10N||Note Added: 0005529|
|2016-12-28 10:43||L10N||Note Added: 0005534|
|2016-12-28 10:44||L10N||Priority||normal => high|
|2016-12-28 10:44||L10N||OS||Windows 10 Pro 64bit => Windows 10 Pro 64bit, Ubuntu|
|2016-12-28 10:44||L10N||Platform||PC Windows 10, IE11 Chrome and F => PC Windows 10, IE11 Chrome Firef|
|2018-01-07 08:41||L10N||Note Added: 0005569|
|2018-01-07 08:43||L10N||Note Added: 0005570|
|2018-01-07 09:00||L10N||File Added: keygen.png|
|2018-01-07 09:03||L10N||Note Added: 0005571|
|2018-01-07 09:49||L10N||Note Added: 0005572|
|2018-01-07 09:50||L10N||Priority||high => urgent|
|2018-01-07 09:50||L10N||Status||new => confirmed|
|2018-01-14 15:03||gukk_devel||Note Added: 0005574|
|2018-01-14 17:40||bjantzen||Note Added: 0005575|
|2018-02-10 10:05||L10N||Note Added: 0005576|
|2018-02-10 10:06||L10N||Tag Attached: certificates|
|2018-02-10 10:06||L10N||Tag Attached: browser|
|2018-02-10 10:06||L10N||Tag Attached: html|
|2018-04-18 21:23||dops||Note Added: 0005585|
|2018-05-02 23:32||RogerCPao||Note Added: 0005587|
|2018-05-02 23:35||RogerCPao||Note Added: 0005588|
|2019-09-07 18:22||vmbentley||Note Added: 0005828|
|2019-09-07 19:09||BarryN||Note Added: 0005829|
|2019-09-07 19:14||BarryN||Note Added: 0005830|
|2019-09-07 19:18||BarryN||Note Added: 0005831|
|2019-09-08 12:16||Ted||Note Added: 0005833|
|2019-09-08 12:16||Ted||Note Edited: 0005833|
|2019-09-08 12:51||Ted||Note Added: 0005834|
|2019-09-08 12:52||Ted||Note Edited: 0005834|
|2019-09-08 13:38||vmbentley||Note Added: 0005835|
|2019-09-09 16:36||BarryN||Note Added: 0005837|
|2019-09-10 20:50||dops||File Added: New Client Certificate.png|
|2019-09-24 21:03||Ted||Assigned To||=> Ted|
|2020-01-06 11:22||Ted||Note Added: 0005857|
|2020-06-27 13:28||L10N||Note Added: 0005895|
|2020-10-21 12:27||Felixishim||Note Added: 0005911|
|2020-10-29 21:31||Ted||Note Added: 0005912|
|2020-10-29 21:33||Ted||Note Edited: 0005912|
|2020-10-29 21:34||Ted||Note Edited: 0005912|
|2020-10-29 22:26||dops||Note Added: 0005913|
|2020-10-29 22:37||Ted||Note Edited: 0005912|
|2020-11-29 19:16||Ted||Note Added: 0005920|
|2020-11-30 00:01||jandd||Note Added: 0005921|
|2021-06-22 23:02||tim.devries||Note Added: 0006017|
|2021-06-22 23:47||tim.devries||Note Added: 0006018|
|2021-06-22 23:56||tim.devries||Note Added: 0006019|
|2021-06-23 00:03||tim.devries||Note Added: 0006020|
|2021-06-26 21:45||Ted||Note Added: 0006021|
|2021-06-26 21:45||Ted||Note Edited: 0006021|
|2021-06-26 21:46||Ted||Note Added: 0006022|
|2021-06-26 21:46||Ted||File Added: certificate-creation-sequence.png|
|2021-06-27 06:45||alkas||Note Added: 0006023|
|2021-06-27 08:07||jandd||Note Added: 0006024|
|2021-06-27 08:33||jandd||Note Added: 0006025|
|2021-06-27 08:33||jandd||File Added: certificate-creation-sequence-2.png|
|2021-06-27 08:33||jandd||File Added: certificate-creation-sequence.txt|
|2021-06-27 08:50||jandd||Note Added: 0006026|
|2021-06-27 10:03||alkas||Note Added: 0006027|
|2021-06-27 10:23||Ted||Note Added: 0006028|
|2021-06-27 10:44||jandd||Note Added: 0006029|
|2021-06-27 10:48||jandd||Note Added: 0006030|
|2021-06-27 10:49||jandd||Note Edited: 0006030|
|2021-06-27 10:49||jandd||Note Edited: 0006030|
|2021-06-27 10:51||Ted||Note Added: 0006031|
|2021-06-27 10:58||jandd||Note Added: 0006032|
|2021-06-27 11:05||jandd||Note Added: 0006033|
|2022-07-28 17:07||jandd||Note Added: 0006131|