Sorry for the late update. First is some clarification on some of the statements I made in my previous blog last week. I misunderstood the usage of the passphrase in the openpgp keyring of the google's e2e library. It served just as a key for the encryption or decryption of the keyring, rather than an identifier of different keyrings. Therefore, for the support of multiple users, only the passphrase sounds not enough, and the google's library stores only one keyring encrypted with the passphrase, given that it is not empty. When an user enters an incorrect passphrase, the library gives the following warning:
As a matter of fact, the localStorage is not modified. Instead, because the HMAC key is also generated from the passphrase, as long as an incorrect passphrase is given, the computed HMAC is not the same as the one stored in localStorage.
In one word, the e2e library stores only one keyring encrypted under the passphrase, and if an incorrect passphrase is entered to access an encrypted keyring, the attempt fails since the HMACs do not match.
A basic file parser was added to the extension. For now, the extension is able to handle AES decryption automatically. For an encrypted file like this,
The cipher for encrypting the message, "aes-256-cbc", is specified after the header. The group number, 22, the group state, 0, and the initialization vector for decrypting the encrypted file key and initialization vector, are shown after the cipher. And the encrypted file key and initialization vector come next, which is followed by the header and the body of the encrypted message. Once the extension knows the current group state, which is obtained from the key server, it unwinds it to previous state if necessary and takes the hash value of the correct state as the key. Using this key, the extension gets the file key and initialization vector, which is encrypted under "aes-256-cbc" by default (note that this cipher may be different from the one specified in the header, and the one in the header is only the cipher for encrypting the message). With file key and initialization vector, the decrypted message is retrieved from the body of the encrypted message.
Finally, there seems to be a bug in injecting codes to subframes. Google does not provide API for injecting code for a specific subframe, so I import a library implemented by a third-party developer to allow me to do so. However, this library, although works, is not stable and fails to inject codes to a subframe sometimes. I just came up with a new idea to inject codes using random number as an identifier for different subframes. I am going to implement this and talk about it if it works in my next blog.