Skip to content

Commit e9fa231

Browse files
committed
fix: update ed25519 to v2
1 parent 8a70282 commit e9fa231

File tree

9 files changed

+49
-51
lines changed

9 files changed

+49
-51
lines changed

examples/http_client.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use {
22
relay_client::{http::Client, ConnectionOptions},
33
relay_rpc::{
4-
auth::{ed25519_dalek::Keypair, rand, AuthToken},
4+
auth::{ed25519_dalek::SigningKey, rand, AuthToken},
55
domain::Topic,
66
},
77
std::{sync::Arc, time::Duration},
@@ -20,7 +20,7 @@ struct Args {
2020
project_id: String,
2121
}
2222

23-
fn create_conn_opts(key: &Keypair, address: &str, project_id: &str) -> ConnectionOptions {
23+
fn create_conn_opts(key: &SigningKey, address: &str, project_id: &str) -> ConnectionOptions {
2424
let aud = Url::parse(address)
2525
.unwrap()
2626
.origin()
@@ -39,10 +39,10 @@ fn create_conn_opts(key: &Keypair, address: &str, project_id: &str) -> Connectio
3939
async fn main() -> anyhow::Result<()> {
4040
let args = Args::from_args();
4141

42-
let key1 = Keypair::generate(&mut rand::thread_rng());
42+
let key1 = SigningKey::generate(&mut rand::thread_rng());
4343
let client1 = Client::new(&create_conn_opts(&key1, &args.address, &args.project_id))?;
4444

45-
let key2 = Keypair::generate(&mut rand::thread_rng());
45+
let key2 = SigningKey::generate(&mut rand::thread_rng());
4646
let client2 = Client::new(&create_conn_opts(&key2, &args.address, &args.project_id))?;
4747

4848
let topic = Topic::generate();

examples/webhook.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use {
44
ConnectionOptions,
55
},
66
relay_rpc::{
7-
auth::{ed25519_dalek::Keypair, rand, AuthToken},
7+
auth::{ed25519_dalek::SigningKey, rand, AuthToken},
88
domain::{DecodedClientId, Topic},
99
jwt::VerifyableClaims,
1010
rpc,
@@ -35,7 +35,7 @@ struct Args {
3535
webhook_server_port: u16,
3636
}
3737

38-
fn create_conn_opts(key: &Keypair, address: &str, project_id: &str) -> ConnectionOptions {
38+
fn create_conn_opts(key: &SigningKey, address: &str, project_id: &str) -> ConnectionOptions {
3939
let aud = Url::parse(address)
4040
.unwrap()
4141
.origin()
@@ -122,26 +122,26 @@ async fn main() -> anyhow::Result<()> {
122122
// Give time for the server to start up.
123123
tokio::time::sleep(Duration::from_millis(500)).await;
124124

125-
let publisher_key = Keypair::generate(&mut rand::thread_rng());
125+
let publisher_key = SigningKey::generate(&mut rand::thread_rng());
126126
let publisher = Client::new(&create_conn_opts(
127127
&publisher_key,
128128
&args.address,
129129
&args.project_id,
130130
))?;
131131
println!(
132132
"[publisher] client id: {}",
133-
DecodedClientId::from(publisher_key.public_key()).to_did_key()
133+
DecodedClientId::from(publisher_key.verifying_key()).to_did_key()
134134
);
135135

136-
let subscriber_key = Keypair::generate(&mut rand::thread_rng());
136+
let subscriber_key = SigningKey::generate(&mut rand::thread_rng());
137137
let subscriber = Client::new(&create_conn_opts(
138138
&subscriber_key,
139139
&args.address,
140140
&args.project_id,
141141
))?;
142142
println!(
143143
"[subscriber] client id: {}",
144-
DecodedClientId::from(subscriber_key.public_key()).to_did_key()
144+
DecodedClientId::from(subscriber_key.verifying_key()).to_did_key()
145145
);
146146

147147
let topic = Topic::generate();

examples/websocket_client.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use {
55
ConnectionOptions,
66
},
77
relay_rpc::{
8-
auth::{ed25519_dalek::Keypair, rand, AuthToken},
8+
auth::{ed25519_dalek::SigningKey, rand, AuthToken},
99
domain::Topic,
1010
},
1111
std::{sync::Arc, time::Duration},
@@ -59,7 +59,7 @@ impl ConnectionHandler for Handler {
5959
}
6060

6161
fn create_conn_opts(address: &str, project_id: &str) -> ConnectionOptions {
62-
let key = Keypair::generate(&mut rand::thread_rng());
62+
let key = SigningKey::generate(&mut rand::thread_rng());
6363

6464
let auth = AuthToken::new("http://example.com")
6565
.aud(address)

relay_client/src/http.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use {
66
},
77
http::{HeaderMap, StatusCode},
88
relay_rpc::{
9-
auth::ed25519_dalek::Keypair,
9+
auth::ed25519_dalek::SigningKey,
1010
domain::{DecodedClientId, SubscriptionId, Topic},
1111
jwt::{self, JwtError, VerifyableClaims},
1212
rpc::{self, Receipt, RequestPayload},
@@ -168,7 +168,7 @@ impl Client {
168168
pub async fn watch_register(
169169
&self,
170170
request: WatchRegisterRequest,
171-
keypair: &Keypair,
171+
keypair: &SigningKey,
172172
) -> Response<rpc::WatchRegister> {
173173
let iat = chrono::Utc::now().timestamp();
174174
let ttl_sec: i64 = request
@@ -180,7 +180,7 @@ impl Client {
180180

181181
let claims = rpc::WatchRegisterClaims {
182182
basic: jwt::JwtBasicClaims {
183-
iss: DecodedClientId::from_key(&keypair.public_key()).into(),
183+
iss: DecodedClientId::from_key(&keypair.verifying_key()).into(),
184184
aud: self.origin.clone(),
185185
iat,
186186
sub: request.service_url,
@@ -212,13 +212,13 @@ impl Client {
212212
pub async fn watch_unregister(
213213
&self,
214214
request: WatchUnregisterRequest,
215-
keypair: &Keypair,
215+
keypair: &SigningKey,
216216
) -> Response<rpc::WatchUnregister> {
217217
let iat = chrono::Utc::now().timestamp();
218218

219219
let claims = rpc::WatchUnregisterClaims {
220220
basic: jwt::JwtBasicClaims {
221-
iss: DecodedClientId::from_key(&keypair.public_key()).into(),
221+
iss: DecodedClientId::from_key(&keypair.verifying_key()).into(),
222222
aud: self.origin.clone(),
223223
iat,
224224
sub: request.service_url,

relay_rpc/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ serde = { version = "1", features = ["derive", "rc"] }
3030
serde-aux = { version = "4", default-features = false }
3131
serde_json = "1"
3232
thiserror = "1"
33-
ed25519-dalek = { git = "https://github.com/dalek-cryptography/ed25519-dalek.git", rev = "7529d65" }
34-
rand = "0.7"
33+
ed25519-dalek = { version = "2", features = ["rand_core"] }
34+
rand = "0.8"
3535
chrono = { version = "0.4", default-features = false, features = [
3636
"std",
3737
"clock",

relay_rpc/src/auth.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use {
44
jwt::{JwtBasicClaims, JwtHeader},
55
},
66
chrono::{DateTime, Utc},
7-
ed25519_dalek::{ed25519::signature::Signature, Keypair, Signer},
7+
ed25519_dalek::{Signer, SigningKey},
88
serde::{Deserialize, Serialize},
99
std::{fmt::Display, time::Duration},
1010
};
@@ -80,7 +80,7 @@ impl AuthToken {
8080
self
8181
}
8282

83-
pub fn as_jwt(&self, key: &Keypair) -> Result<SerializedAuthToken, Error> {
83+
pub fn as_jwt(&self, key: &SigningKey) -> Result<SerializedAuthToken, Error> {
8484
let iat = self.iat.unwrap_or_else(Utc::now);
8585
let aud = self.aud.as_deref().unwrap_or(DEFAULT_TOKEN_AUD);
8686

@@ -89,7 +89,7 @@ impl AuthToken {
8989
}
9090

9191
pub fn encode_auth_token(
92-
key: &Keypair,
92+
key: &SigningKey,
9393
sub: impl Into<String>,
9494
aud: impl Into<String>,
9595
iat: DateTime<Utc>,
@@ -105,7 +105,7 @@ pub fn encode_auth_token(
105105

106106
let claims = {
107107
let data = JwtBasicClaims {
108-
iss: DecodedClientId::from_key(&key.public_key()).into(),
108+
iss: DecodedClientId::from_key(&key.verifying_key()).into(),
109109
sub: sub.into(),
110110
aud: aud.into(),
111111
iat: iat.timestamp(),
@@ -121,7 +121,7 @@ pub fn encode_auth_token(
121121
let signature = {
122122
let data = key.sign(message.as_bytes());
123123

124-
encoder.encode(data.as_bytes())
124+
encoder.encode(&data.to_bytes())
125125
};
126126

127127
Ok(SerializedAuthToken(format!("{message}.{signature}")))

relay_rpc/src/domain.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use {
99
new_type,
1010
},
1111
derive_more::{AsMut, AsRef},
12-
ed25519_dalek::PublicKey,
12+
ed25519_dalek::VerifyingKey,
1313
serde::{Deserialize, Serialize},
1414
serde_aux::prelude::deserialize_number_from_string,
1515
std::{str::FromStr, sync::Arc},
@@ -82,7 +82,7 @@ pub struct DidKey(
8282
#[serde(with = "crate::serde_helpers::client_id_as_did_key")] pub DecodedClientId,
8383
);
8484

85-
impl From<DidKey> for PublicKey {
85+
impl From<DidKey> for VerifyingKey {
8686
fn from(val: DidKey) -> Self {
8787
val.0.as_public_key()
8888
}
@@ -119,24 +119,24 @@ impl DecodedClientId {
119119
}
120120

121121
#[inline]
122-
pub fn from_key(key: &PublicKey) -> Self {
122+
pub fn from_key(key: &VerifyingKey) -> Self {
123123
Self(*key.as_bytes())
124124
}
125125

126126
#[inline]
127-
pub fn as_public_key(&self) -> PublicKey {
127+
pub fn as_public_key(&self) -> VerifyingKey {
128128
// We know that the length is correct, so we can just unwrap.
129-
PublicKey::from_bytes(&self.0).unwrap()
129+
VerifyingKey::from_bytes(&self.0).unwrap()
130130
}
131131
}
132132

133-
impl From<PublicKey> for DecodedClientId {
134-
fn from(key: PublicKey) -> Self {
133+
impl From<VerifyingKey> for DecodedClientId {
134+
fn from(key: VerifyingKey) -> Self {
135135
Self::from_key(&key)
136136
}
137137
}
138138

139-
impl From<DecodedClientId> for PublicKey {
139+
impl From<DecodedClientId> for VerifyingKey {
140140
fn from(val: DecodedClientId) -> Self {
141141
val.as_public_key()
142142
}

relay_rpc/src/jwt.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use {
22
crate::domain::DidKey,
33
chrono::Utc,
4-
ed25519_dalek::{ed25519::signature::Signature, Keypair, PublicKey, Signer},
4+
ed25519_dalek::{Signer, SigningKey},
55
serde::{de::DeserializeOwned, Deserialize, Serialize},
66
std::collections::HashSet,
77
};
@@ -103,20 +103,19 @@ pub trait VerifyableClaims: Serialize + DeserializeOwned {
103103
/// Encodes the claims into a JWT string, signing it with the provided key.
104104
/// Returns an error if the provided key does not match the public key in
105105
/// the claims (`iss`), or if serialization fails.
106-
fn encode(&self, key: &Keypair) -> Result<String, JwtError> {
107-
let public_key = PublicKey::from_bytes(self.basic().iss.as_ref())
108-
.map_err(|_| JwtError::InvalidKeypair)?;
106+
fn encode(&self, key: &SigningKey) -> Result<String, JwtError> {
107+
let public_key = self.basic().iss.0.as_public_key();
109108

110109
// Make sure the keypair matches the public key in the claims.
111-
if public_key != key.public_key() {
110+
if public_key != key.verifying_key() {
112111
return Err(JwtError::InvalidKeypair);
113112
}
114113

115114
let encoder = &data_encoding::BASE64URL_NOPAD;
116115
let header = encoder.encode(serde_json::to_string(&JwtHeader::default())?.as_bytes());
117116
let claims = encoder.encode(serde_json::to_string(self)?.as_bytes());
118117
let message = format!("{header}.{claims}");
119-
let signature = encoder.encode(key.sign(message.as_bytes()).as_bytes());
118+
let signature = encoder.encode(&key.sign(message.as_bytes()).to_bytes());
120119

121120
Ok(format!("{message}.{signature}"))
122121
}
@@ -240,7 +239,8 @@ mod test {
240239
domain::ClientId,
241240
jwt::{JwtBasicClaims, JwtError, VerifyableClaims, JWT_VALIDATION_TIME_LEEWAY_SECS},
242241
},
243-
ed25519_dalek::Keypair,
242+
ed25519_dalek::SigningKey,
243+
rand::rngs::OsRng,
244244
std::{collections::HashSet, time::Duration},
245245
};
246246

@@ -283,7 +283,7 @@ mod test {
283283
let jwt = Jwt("eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6a2V5Ono2TWtvZEhad25lVlJTaHRhTGY4SktZa3hwREdwMXZHWm5wR21kQnBYOE0yZXh4SGwiLCJzdWIiOiJjNDc5ZmU1ZGM0NjRlNzcxZTc4YjE5M2QyMzlhNjViNThkMjc4Y2FkMWMzNGJmYjBiNTcxNmU1YmI1MTQ5MjhlIiwiYXVkIjoid3NzOi8vcmVsYXkud2FsbGV0Y29ubmVjdC5jb20iLCJpYXQiOjE2NTY5MTAwOTcsImV4cCI6NDgxMjY3MDA5N30.nLdxz4f6yJ8HsWZJUvpSHjFjoat4PfJav-kyqdHj6JXcX5SyDvp3QNB9doyzRWb9jpbA36Av0qn4kqLl-pGuBg".to_owned());
284284
assert!(matches!(jwt.decode(&aud), Err(JwtError::Serialization(..))));
285285

286-
let keypair = Keypair::generate(&mut rand::thread_rng());
286+
let keypair = SigningKey::generate(&mut OsRng);
287287
let sub: String = "test".to_owned();
288288

289289
// IAT in future.

relay_rpc/src/rpc/watch.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -125,25 +125,23 @@ mod test {
125125
super::*,
126126
crate::{auth::RELAY_WEBSOCKET_ADDRESS, domain::DecodedClientId},
127127
chrono::DateTime,
128-
ed25519_dalek::Keypair,
128+
ed25519_dalek::SigningKey,
129129
};
130130

131-
const KEYPAIR: [u8; 64] = [
131+
const KEYPAIR: [u8; 32] = [
132132
215, 142, 127, 216, 153, 183, 205, 110, 103, 118, 181, 195, 60, 71, 5, 221, 100, 196, 207,
133-
81, 229, 11, 116, 121, 235, 104, 1, 121, 25, 18, 218, 83, 216, 230, 100, 248, 132, 110, 55,
134-
65, 221, 87, 66, 160, 36, 95, 116, 86, 169, 49, 107, 17, 13, 50, 22, 147, 199, 109, 125,
135-
155, 89, 190, 186, 171,
133+
81, 229, 11, 116, 121, 235, 104, 1, 121, 25, 18, 218, 83,
136134
];
137135

138136
#[test]
139137
fn watch_register_jwt() {
140-
let key = Keypair::from_bytes(&KEYPAIR).unwrap();
138+
let key = SigningKey::from_bytes(&KEYPAIR);
141139
let iat = DateTime::parse_from_rfc3339("2000-01-01T00:00:00Z").unwrap();
142140
let exp = DateTime::parse_from_rfc3339("3000-01-01T00:00:00Z").unwrap();
143141

144142
let claims = WatchRegisterClaims {
145143
basic: JwtBasicClaims {
146-
iss: DecodedClientId::from_key(&key.public_key()).into(),
144+
iss: DecodedClientId::from_key(&key.verifying_key()).into(),
147145
aud: RELAY_WEBSOCKET_ADDRESS.to_owned(),
148146
sub: "https://example.com".to_owned(),
149147
iat: iat.timestamp(),
@@ -172,13 +170,13 @@ mod test {
172170

173171
#[test]
174172
fn watch_unregister_jwt() {
175-
let key = Keypair::from_bytes(&KEYPAIR).unwrap();
173+
let key = SigningKey::from_bytes(&KEYPAIR);
176174
let iat = DateTime::parse_from_rfc3339("2000-01-01T00:00:00Z").unwrap();
177175
let exp = DateTime::parse_from_rfc3339("3000-01-01T00:00:00Z").unwrap();
178176

179177
let claims = WatchUnregisterClaims {
180178
basic: JwtBasicClaims {
181-
iss: DecodedClientId::from_key(&key.public_key()).into(),
179+
iss: DecodedClientId::from_key(&key.verifying_key()).into(),
182180
aud: RELAY_WEBSOCKET_ADDRESS.to_owned(),
183181
sub: "https://example.com".to_owned(),
184182
iat: iat.timestamp(),
@@ -205,14 +203,14 @@ mod test {
205203

206204
#[test]
207205
fn watch_event_jwt() {
208-
let key = Keypair::from_bytes(&KEYPAIR).unwrap();
206+
let key = SigningKey::from_bytes(&KEYPAIR);
209207
let iat = DateTime::parse_from_rfc3339("2000-01-01T00:00:00Z").unwrap();
210208
let exp = DateTime::parse_from_rfc3339("3000-01-01T00:00:00Z").unwrap();
211209
let topic = Topic::from("474e88153f4db893de42c35e1891dc0e37a02e11961385de0475460fb48b8639");
212210

213211
let claims = WatchEventClaims {
214212
basic: JwtBasicClaims {
215-
iss: DecodedClientId::from_key(&key.public_key()).into(),
213+
iss: DecodedClientId::from_key(&key.verifying_key()).into(),
216214
aud: RELAY_WEBSOCKET_ADDRESS.to_owned(),
217215
sub: "https://example.com".to_owned(),
218216
iat: iat.timestamp(),

0 commit comments

Comments
 (0)