Skip to content
This repository has been archived by the owner on Oct 5, 2023. It is now read-only.

can i ask you about this project #1

Open
wants to merge 52 commits into
base: master
Choose a base branch
from

Conversation

chunamanh
Copy link

Hello, i want to ask you about this project but can't think of any better way than do this.Is this project still active? And can i use this for my project with roundcube 1.6.0?

Some functions now require namespace prefixes.
I don't think it's going to work out, though.  Roundcube will need to call rc_openpgpjs's functions, but I don't think you can do that unless all of Roundcube's javascript gets webpacked too.
It doesn't actually work yet, becuase the rc_openpgpjs code is referencing an out-of-date version of openpgpjs, but it at least shows that it can work.
I have not tested what happens if there's an error, but it looks like a lot of errors are swallowed rather than being displayed to the user.
I think phones might have ways of submitting the form using their keyboard thingy.  That might not qualify as hitting enter in the search box, which we were using to manually trigger the click.
There was a "passphrase" input on the import private key pane.  You don't actually need a passphrase in order to import a private key; only to actually use it.
It is able to create an encrypted string from a message.  It doesn't work if you encrypt+sign.  The string is logged to the console, but it doesn't actually send...
Here's what was going on:  In testing, my email appeared as ryan@dovecot.  When I would generate a key with that id, I got an error saying that it was an invalid user id.  I thought, "the authors of openpgpjs wouldn't have done something as ridiculous as apply a regex to the email address to check if it had a tld or something!  The error must be somewhere in rc_openpgpjs."  So I found what looked like an error and fixed it.

But it turns out the problem does reside somewhere in rc_openpgpjs.  They really do have a regex that attempts to detect "invalid" email addresses.  I cannot fathom why.  They do not envision that a pgp setup may be used in an all-internal environment, where it is valid to use a hostname other than one from the public DNS from ICANN.  Is this in some sort of PGP spec?  Or is it just the shortsightedness that seems to take hold of everybody when someone mentions email addresses and they say "Oh, I know what an email address looks like!  I better enforce my preconceived notions, even though nothing would go wrong if I didn't!"

The function in openpgpjs is "isEmailAddress", in util.js.  I should fix it.
I did that to test the state machine and accidentally left it in, oops.

Also, this commit sets busy to true while encrypting.
This is a compromise which allows exceptions to function properly.
Instead of that awkward thing where I keep calling the send command and checking on the state machine.
galaxor added 22 commits April 20, 2018 19:08
What I was doing before was creating anonymous functions and registering them as handlers.  The problem was, I was not deregistering the handlers.  Instead, I'm using a single handler with a global variable for the resolve function.
Previously, there was a button with an onclick handler.  That meant you had to click the button, you couldn't hit enter from within the passphrase text box.
I've hit a problem where openpgpjs won't sign, and I don't know why.  Is it a bug in openpgpjs?

It crashes at openpgpjs's cleartext.js:86, with "privateKeys[i].isPublic is not a function".  By inserting debugging statements, I've found that, while privateKeys[i].isPublic is indeed not a function, privateKeys[i].key.isPublic is.  Have I passed in something wrong, or is there a bug in openpgpjs?  Perhaps I have not actually decrypted the privateKey like I think I did, and that's why isPublic isn't where the signDetached function expects it?
There was no bug in the openpgp sign function.  It turned out I was calling the decryptKey function twice -- once correctly, and once incorrectly.  I'd forgotten about the incorrect one, and this was the source of my confusion.
Not working: Attach public key.
Not tested:
  - Remember the passphrase for this session.
  - A privkey that is not encrypted.

I'd also like to unify the encrypt with the encrypt+sign, so I have fewer branches.
I had copy/pasted the signing code and forgotten to change it from "sign" to "encrypt".  Oops!
If an individual key had N userids associated with it, we used to just show one of the userids, but show it N times.  Now, we show all the userids.

I'd be happier if we had a table like the one in the key manager, so it was more obvious that all the userids were for the same key.  But this works.
Oh!  Prolly cuz it should show spinner while signing/encrypting msg.  Decrypt key is prolly too fast.
In the key select dialog, when the user has entered a passphrase, we want to hide the submit button and show "working" until we're done encrypting, because it might take a second or two.  Previously, we removed the spinner after decrypting the private key, which was too soon.

However, even now, I never see the spinner.  I don't know why.  If I add a 3sec delay before starting the encryption, I do see the spinner.
Previously, it was using the first eight chars of the fingerprint, which is not used anywhere else in openpgp or gpg, so it would not be useful.  The keyId is something that is used.  By default, command-line gpg shows the "short format" keyId, and that's a more human-digestible string.  I wish we could use that here, but openpgp's getKeyId, but openpgpjs does not do the short format.

Another important reason to switch to keyId is for the "Remember for this session" feature of the key selector.  Previously, what we'd been remembering was the position of the key in the array of all private keys.  That means that if the user selected a key and remembered it, and then went to the key manager and deleted an earlier key from the keyring, then that position index is no longer valid, and points to a different key.  When we remember, we also remember the passphrase.  The remembered passphrase probably doesn't work on the new key, and if it does, that's worse because the user will think we've been remembering one key, and we're actually using a different one!

To overcome this problem, we will remember the keyId and passphrase.

Now, we could simply remember the ascii-armored version of the decrypted private key.  After all, the keyId and passphrase can be used to obtain the decrypted private key.  But it just made me nervous to have that in memory between sessions.

So instead, we will remember keyId and passphrase.  We will use the keyId to look up the key later, when we want to use it for signing.  And that means we need an id we can look things up by.  The choices listed by openpgpjs's getKeysForId function are: keyId or full fingerprint.  First eight chars of the fingerprint cannot be used to look anything up.

So, the state that the code is in right now:
The key selector shows the keyIds.  Clicking on a key will show it.  That's all I've tested since changing this, and that's probably all that works.  Let's go change the rest of it, so it's all about keyId!
Previously, we decrypted the private key twice:  Once to see if the passphrase was correct.  Then we would throw that decrypted key away, and then decrypt it a second time, when we were about to sign the message.

It was easy to do this because, once we found that the passphrase worked, the object we passed back contained a position index.  We would use that index to look up the key in the keyring.  We used to do that because it was easy to store the position index in the sessionStorage, if the user asked to use the same key and remember the passphrase each time.  That meant we could have one code path for both situations: 1) a key selected just now, 2) a key pulled from sessionStorage.

But, for reasons already explained in an earlier commit log, the position index was not a reliable way to identify the key.  (What if the keyring changed between saving the preference and using it?)  So I'm changing it so that the sessionStorage stores the keyId instead of a position index.  The logic to get the decrypted key from the keyId requires sufficient library-specific code that I would want to put it in rc_openpgpjs_crypto instead of rc_openpgpjs.  But it seemed silly to do that only to require us to decrypt the key a second time, in the case of a key selected just now.

For a key pulled from sessionStorage, we'll just have a different code path that decrypts it. (not implemented yet)

(NOTE: I should test what happens if the key gets deleted from the keyring between saving the preference and using it!  We should detect that case and pop up the key select dialog, but we probably don't.)
You can click the checkbox to remember the key selection and passphrase for this session.  That will work.

Now, the keyring may have changed between the time when you remembered the preference and the time when you use it to send a message.  If the key is deleted or the passphrase changed, then you won't be able to decrypt the key.  In that case, we simply present the key selection dialog again.
This commit adds some HTML to the compose messages interface.

In the current UI, when you are about to send a signed message, you're given a choice of what key to sign with, and you're made to enter the passphrase.  You may want to remember this selection, and remember the passphrase so you don't have to enter it again next time.  We have a checkbox on the form when you enter your passphrase.  If you click the checkbox, the passphrase and selection are saved for the remainder of the browser session.

However, what if you change your mind and want to start using a different key?  What if you're about to hand your computer to someone else and don't want them to be able to sign messages without having to enter your passphrase?  Currently, there is no way to forget your selection or your passphrase without closing your browser (or something; I'm not entirely clear on how sessionStorage is supposed to work).

The idea is that, if you have a remembered key, it should show a UI element showing you that you have a key remembered.  That way, you won't click send thinking that it'll give you a choice of private key when actually, it remembered a previous selection.  If you do that, you may sign a message with a private key you did not intend to.  Maybe you didn't want people to know that those private keys belonged to the same person.  Well, this UI should let you see that this will happen.  If you make that mistake, then - hey - at least you were warned.

Also, when you see what key is remembered, you'll have the option to forget the key by clicking a button.  If you do that, then next time you try to sign a message, you'll get the key selection / passphrase entering dialog again.

Okay, but I just noticed something:  Maybe you want to remember the passphrase for a bunch of different private keys, because you are reading encrypted messages.  Remembering those passphrases should be different from remembering what key you want to be the default when you sign a message.  How should we separate these ideas in the UI?  I don't know yet, but think about it.
@b-turchyn
Copy link
Owner

b-turchyn commented Oct 21, 2022

Hey @chunamanh; I admittedly haven't looked at this project since I forked it so long ago (I want to say this was before Github had the Archive functionality, but that's neither here nor there). I ended up not making any progress due to pretty much the same reasons the original author did: lack of motivation, resources, etc.

In its current state, I really didn't do anything to it when compared to the original fork. The galaxor fork has had more activity, and so it may be better to work from that repo instead.

I have three options you could consider here:

  1. Take a look at the galaxor fork and look at installing it from there
  2. If you're not against browser addons, I believe Mailvelope has first-class support in Roundcube as of v1.2.0, released in 2016.
  3. The Enigma plugin is an option which would allow you to store your PGP keypair on the server. I would highly recommend you do not take this approach, even if you run and own the infrastructure Roundcube sits on, because if that server gets compromised you've effectively burnt that PGP keypair and the trust you've built with it.

Hope that helps!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants