Skip to content

Commit bbdb0f7

Browse files
committed
Flesh out the README
1 parent d3fb5a1 commit bbdb0f7

File tree

1 file changed

+77
-10
lines changed

1 file changed

+77
-10
lines changed

README.md

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,86 @@
55
[Latest Version]: https://img.shields.io/crates/v/ece.svg
66
[crates.io]: https://crates.io/crates/ece
77

8-
*This crate has not been security reviewed yet, use at your own risk ([tracking issue](https://github.com/mozilla/rust-ece/issues/18))*.
8+
*This crate has not been security reviewed yet, use at your own risk
9+
([tracking issue](https://github.com/mozilla/rust-ece/issues/18))*.
910

10-
[ece](https://crates.io/crates/ece) is a Rust implementation of the HTTP Encrypted Content-Encoding standard (RFC 8188). It is a port of the [ecec](https://github.com/web-push-libs/ecec) C library.
11-
This crate is destined to be used by higher-level Web Push libraries, both on the server and the client side.
11+
The [ece](https://crates.io/crates/ece) crate is a Rust implementation of Message Encryption for Web Push
12+
([RFC8291](https://tools.ietf.org/html/rfc8291)) and the HTTP Encrypted Content-Encoding scheme
13+
([RFC8188](https://tools.ietf.org/html/rfc8188)) on which it is based.
1214

13-
[Documentation](https://docs.rs/ece/)
15+
It provides low-level cryptographic "plumbing" and is destined to be used by higher-level Web Push libraries, both on
16+
the server and the client side. It is a port of the [ecec](https://github.com/web-push-libs/ecec) C library.
1417

15-
## Cryptographic backends
16-
17-
This crate is designed to be used with different crypto backends. At the moment only [openssl](https://github.com/sfackler/rust-openssl) is supported.
18+
[Full Documentation](https://docs.rs/ece/)
1819

1920
## Implemented schemes
2021

21-
Currently, two HTTP ece schemes are available to consumers of the crate:
22-
- The newer [RFC8188](https://tools.ietf.org/html/rfc8188) `aes128gcm` standard.
23-
- The legacy [draft-03](https://tools.ietf.org/html/draft-ietf-httpbis-encryption-encoding-03) `aesgcm` scheme.
22+
This crate implements both the published Web Push Encryption scheme, and a legacy scheme from earlier drafts
23+
that is still widely used in the wild:
24+
25+
* `aes128gcm`: the scheme described in [RFC8291](https://tools.ietf.org/html/rfc8291) and
26+
[RFC8188](https://tools.ietf.org/html/rfc8188)
27+
* `aesgcm`: the draft scheme described in
28+
[draft-ietf-webpush-encryption-04](https://tools.ietf.org/html/draft-ietf-webpush-encryption-04) and
29+
[draft-ietf-httpbis-encryption-encoding-03](https://tools.ietf.org/html/draft-ietf-httpbis-encryption-encoding-03_)
30+
31+
## Usage
32+
33+
To receive messages via WebPush, the receiver must generate an EC keypair and a symmetric authentication secret,
34+
then distribute the public key and authentication secret to the sender:
35+
36+
```
37+
let (keypair, auth_secret) = ece::generate_keypair_and_auth_secret()?;
38+
let pubkey = keypair.pub_as_as_raw();
39+
// Base64-encode the `pubkey` and `auth_secret` bytes and distribute them to the sender.
40+
```
41+
42+
The sender can encrypt a Web Push message to the receiver's public key:
43+
44+
```
45+
let ciphertext = ece::encrypt(pubkey, auth_secret, b"payload")?;
46+
```
47+
48+
And the receiver can decrypt it using their private key:
49+
50+
```
51+
let plaintext = ece::decrypt(keypair, auth_secret)?;
52+
```
53+
54+
That's pretty much all there is to it! It's up to the higher-level library to manage distributing the encrypted payload,
55+
typically by arranging for it to be included in a HTTP response with `Content-Encoding: aes128gcm` header.
56+
57+
### Legacy `aesgcm` encryption
58+
59+
The legacy `aesgcm` scheme is more complicated, because it communicates some encryption parameters in HTTP header fields
60+
rather than as part of the encrypted payload. When used for encryption, the sender must deal with `Encryption` and
61+
`Crypto-Key` headers in addition to the ciphertext:
62+
63+
```
64+
let encrypted_block = ece::AesGcmEceWebPushImpl::encrypt(pubkey, auth_secret, b"payload")?;
65+
for (header, &value) in encrypted_block.headers().iter() {
66+
// Set header to corresponding value
67+
}
68+
// Send encrypted_block.ciphertext as the body
69+
```
70+
71+
When receiving an `aesgcm` message, the receiver needs to parse encryption parameters from the `Encryption`
72+
and `Crypto-Key` fields:
73+
74+
```
75+
// Parse `rs`, `salt` and `dh` from the `Encryption` and `Crypto-Key` headers.
76+
// You'll need to consult the spec for how to do this; we might add some helpers one day.
77+
let encrypted_block = ece::AesGcmEncryptedBlock::new(dh, rs, salt, ciphertext);
78+
let plaintext = ece::AesGcmEceWebPushImpl::decrypt(keypair, auth_secret, encrypted_block)?;
79+
```
80+
81+
### Unimplemented Features
82+
83+
* We do not implement streaming encryption or decryption, although the ECE scheme is designed to permit it.
84+
* The application cannot control what padding is apply during encryption; we randonly select a length of padding to add
85+
during encryption, but the RFC suggests that the best choice of strategy [is application-dependant](https://tools.ietf.org/html/rfc8188#section-4.8)
86+
87+
## Cryptographic backends
88+
89+
This crate is designed to use pluggable backend implementations of low-level crypto primitives. different crypto
90+
backends. At the moment only [openssl](https://github.com/sfackler/rust-openssl) is supported.

0 commit comments

Comments
 (0)