Since pwnmail is based on:
message = "some message here"
key = random(32)
nonce = random(12)
e_key = rsa.EncryptOAEP(key, receiver.public_key)
e_message = aes.EncryptGCM(message, key)
signature = rsa.SignPSS(e_message, sender.private_key)
transmit([signature, e_key, nonce, e_message])
and webcrypto supports both RSA OAEP and AES GCM, in theory it's possible to implement a pure javascript pwnmail client.
On each pwnfile page there should be a button like "Message Me", which would open a dialog asking for the message, encrypt it with webcrypto in the browser and then send it to api.pwnagotchi.ai as the pwngrid binary itself would do.
This is the encryption function and this is [how to send signed and encrypted data to the API].(https://github.com/evilsocket/pwngrid/blob/master/api/peer_inbox.go#L129).
API reference https://pwnagotchi.ai/api/grid/#get-api-v1-unit-inbox-id
My only hangup is how does the private key get handed off in the browser so the out going message is signed? If I am ignorant on something here let me know. This sounds doable for me, but I'm just rolling it around right now.
Same issue here, started working on this but unless I'm missing something, for this to work, the form should have at least a "Your private key" field which would look very scary to me if I encountered it in the wild. Assuming this is how you imagined it, maybe we could make the signature optional ?
there is no private key involvement, that's the whole point of RSA: the message you want to send to me, let's say, will be encrypted with my public key (which is already public from the API), and the decryption will happen with my private key. But decryption doesn't happen in the browser, only the encryption :D
if you check this line you will see i'm using the recipient public key for the encryption. The private key is never disclosed and it's only left on the device for offline (and isolated) decryption.
it's like a mailbox, anybody can send a message that you can decrypt offline with your private key by using the pwngrid binary as explained in the pwnmail docs :D
Ok, so I think the issue is that I assumed you also wanted to sign the message, but I think I was mistaken.
The message sent through the pwnfile page should be encrypted with the recipient's public key, but not signed by the sender. Am I correct ?
correct, sorry i forgot to mention that signature is not doable in browser for the very reason you remarked, my bad :D
Ah it all makes sense now 馃憤
I should have a PR soon.
and it kind of makes sense, as it's a public inbox ... maybe we can make users opt-in or opt-out to it depending on some specific field they send
thanks a lot @jargot !
Hitting the POST /api/v1/unit/<fingerprint>/inbox endpoint returns an unauthorized error which I tracked down to auth.go
The API seems to expect this endpoint to authenticate through a token, however, I couldn't find any login component on pwnagotchi.ai...
Unless I'm missing something, the API should be modified so that this particular endpoint does not need to check for valid authentification. Is that something you'd be OK with ?
I am still unfamiliar with the scope of the changes needed, but totally willing to dive in the Go code if that's something you'd consider.
Here's the login procedure https://pwnagotchi.ai/api/grid/#post-api-v1-unit-enroll
POST /api/v1/unit/enroll
I've seen this but based on the expected request for POST /api/v1/unit/enroll
{
"identity": "alpha@ca1225b86dc35fef90922d83421d2fc9c824e95b864cfa62da7bea64ffb05aea",
"public_key": "... BASE64(unit.public_key_pem) ...",
"signature": "... BASE64(SIGN(identity, unit.private_key)) ...",
"data": "... misc unit data ..."
}
and even the name of the endpoint, I'm confused about the spec of the "Message Me" feature.
I understood it in a way that any user (owning a Pwnagotchi or not) would visit any Pwnfile page and be able to send a message to the corresponding device.
Having to login through an endpoint called POST /api/v1/unit/enroll seems to indicate only Pwnagotchi owners can use pwnmail and the request payload expects parameters that seems very incongruent with a web form (since you can hardly generate a trustable public/private key on a web app).
So I'm seeing 2 solutions:
__WEB suffix or something similar), and automatically generate a public + private key combination, sign the message and automatically export the public + private key combination to the sender. This would seem untrustworthy to me, personally, and pretty cumbersome UX wise if you want to re-use them.pwnmailI understood it in a way that any user (owning a Pwnagotchi or not) would visit any Pwnfile page and be able to send a message to the corresponding device.
i understand that you send the message from your pwnagotchi with a webinterface to a fingerprint over the local-API:
POST /api/v1/unit/{fingerprint}/inbox
Send a message to a unit by its fingerprint. The content will be automatically encrypted and signed locally by pwngrid.
no need to use the grid-api with auth. all the auth-magic makes the local grid binary in background.
or am I getting something wrong here?
and yes: the thread here started with using grid-api.
@jargot i can confirm - basically can't send pwnmail message without JWT Token which can only be obtained by enrolled device. Obviously this could be automated by generating RSA keys and enrolling in the browser.
The feature could use browsers LocalStorage to store the private key and yes - this is untrustworthy at some point but then again how bad can this be abused? I mean the worst thing is someone spoofing someone's other identity as "sender" of pwnmail message, which isn't a sensitive info
imho, there is another issue with this approach - this basically can be abused by trolls to "spam" all the pwnagotichis (it actually already it possible the list of all devices is available at https://api.pwnagotchi.ai/api/v1/units). Although i can be oversensitive at this point ...
anyway the whole code should be on https://github.com/evilsocket/www.pwnagotchi.ai ?
yep i understand the issues and yes i agree people would probably abuse this ... let's close this issue for now?