1
- use reqwest:: header :: { HeaderValue , ACCEPT } ;
1
+ use reqwest;
2
2
use std:: fmt:: Debug ;
3
3
4
+ use super :: { request, sign:: Signer } ;
5
+
4
6
/// Represents an ActivityPub inbox.
5
7
///
6
8
/// It routes an incoming Activity through the registered handlers.
@@ -10,7 +12,50 @@ use std::fmt::Debug;
10
12
/// ```rust
11
13
/// # extern crate activitypub;
12
14
/// # use activitypub::{actor::Person, activity::{Announce, Create}, object::Note};
15
+ /// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa};
16
+ /// # use once_cell::sync::Lazy;
13
17
/// # use plume_common::activity_pub::inbox::*;
18
+ /// # use plume_common::activity_pub::sign::{gen_keypair, Error as SignError, Result as SignResult, Signer};
19
+ /// #
20
+ /// # static MY_SIGNER: Lazy<MySigner> = Lazy::new(|| MySigner::new());
21
+ /// #
22
+ /// # struct MySigner {
23
+ /// # public_key: String,
24
+ /// # private_key: String,
25
+ /// # }
26
+ /// #
27
+ /// # impl MySigner {
28
+ /// # fn new() -> Self {
29
+ /// # let (pub_key, priv_key) = gen_keypair();
30
+ /// # Self {
31
+ /// # public_key: String::from_utf8(pub_key).unwrap(),
32
+ /// # private_key: String::from_utf8(priv_key).unwrap(),
33
+ /// # }
34
+ /// # }
35
+ /// # }
36
+ /// #
37
+ /// # impl Signer for MySigner {
38
+ /// # fn get_key_id(&self) -> String {
39
+ /// # "mysigner".into()
40
+ /// # }
41
+ /// #
42
+ /// # fn sign(&self, to_sign: &str) -> SignResult<Vec<u8>> {
43
+ /// # let key = PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.as_ref()).unwrap())
44
+ /// # .unwrap();
45
+ /// # let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &key).unwrap();
46
+ /// # signer.update(to_sign.as_bytes()).unwrap();
47
+ /// # signer.sign_to_vec().map_err(|_| SignError())
48
+ /// # }
49
+ /// #
50
+ /// # fn verify(&self, data: &str, signature: &[u8]) -> SignResult<bool> {
51
+ /// # let key = PKey::from_rsa(Rsa::public_key_from_pem(self.public_key.as_ref()).unwrap())
52
+ /// # .unwrap();
53
+ /// # let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &key).unwrap();
54
+ /// # verifier.update(data.as_bytes()).unwrap();
55
+ /// # verifier.verify(&signature).map_err(|_| SignError())
56
+ /// # }
57
+ /// # }
58
+ /// #
14
59
/// # struct User;
15
60
/// # impl FromId<()> for User {
16
61
/// # type Error = ();
@@ -23,6 +68,10 @@ use std::fmt::Debug;
23
68
/// # fn from_activity(_: &(), obj: Person) -> Result<Self, Self::Error> {
24
69
/// # Ok(User)
25
70
/// # }
71
+ /// #
72
+ /// # fn get_sender() -> &'static dyn Signer {
73
+ /// # &*MY_SIGNER
74
+ /// # }
26
75
/// # }
27
76
/// # impl AsActor<&()> for User {
28
77
/// # fn get_inbox_url(&self) -> String {
@@ -42,6 +91,10 @@ use std::fmt::Debug;
42
91
/// # fn from_activity(_: &(), obj: Note) -> Result<Self, Self::Error> {
43
92
/// # Ok(Message)
44
93
/// # }
94
+ /// #
95
+ /// # fn get_sender() -> &'static dyn Signer {
96
+ /// # &*MY_SIGNER
97
+ /// # }
45
98
/// # }
46
99
/// # impl AsObject<User, Create, &()> for Message {
47
100
/// # type Error = ();
@@ -311,42 +364,25 @@ pub trait FromId<C>: Sized {
311
364
id : & str ,
312
365
proxy : Option < reqwest:: Proxy > ,
313
366
) -> Result < Self :: Object , ( Option < serde_json:: Value > , Self :: Error ) > {
314
- if let Some ( proxy) = proxy {
315
- reqwest:: ClientBuilder :: new ( ) . proxy ( proxy)
316
- } else {
317
- reqwest:: ClientBuilder :: new ( )
318
- }
319
- . connect_timeout ( Some ( std:: time:: Duration :: from_secs ( 5 ) ) )
320
- . build ( )
321
- . map_err ( |_| ( None , InboxError :: DerefError . into ( ) ) ) ?
322
- . get ( id)
323
- . header (
324
- ACCEPT ,
325
- HeaderValue :: from_str (
326
- & super :: ap_accept_header ( )
327
- . into_iter ( )
328
- . collect :: < Vec < _ > > ( )
329
- . join ( ", " ) ,
330
- )
331
- . map_err ( |_| ( None , InboxError :: DerefError . into ( ) ) ) ?,
332
- )
333
- . send ( )
334
- . map_err ( |_| ( None , InboxError :: DerefError ) )
335
- . and_then ( |mut r| {
336
- let json: serde_json:: Value = r
337
- . json ( )
338
- . map_err ( |_| ( None , InboxError :: InvalidObject ( None ) ) ) ?;
339
- serde_json:: from_value ( json. clone ( ) )
340
- . map_err ( |_| ( Some ( json) , InboxError :: InvalidObject ( None ) ) )
341
- } )
342
- . map_err ( |( json, e) | ( json, e. into ( ) ) )
367
+ request:: get ( id, Self :: get_sender ( ) , proxy)
368
+ . map_err ( |_| ( None , InboxError :: DerefError ) )
369
+ . and_then ( |mut r| {
370
+ let json: serde_json:: Value = r
371
+ . json ( )
372
+ . map_err ( |_| ( None , InboxError :: InvalidObject ( None ) ) ) ?;
373
+ serde_json:: from_value ( json. clone ( ) )
374
+ . map_err ( |_| ( Some ( json) , InboxError :: InvalidObject ( None ) ) )
375
+ } )
376
+ . map_err ( |( json, e) | ( json, e. into ( ) ) )
343
377
}
344
378
345
379
/// Builds a `Self` from its ActivityPub representation
346
380
fn from_activity ( ctx : & C , activity : Self :: Object ) -> Result < Self , Self :: Error > ;
347
381
348
382
/// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database)
349
383
fn from_db ( ctx : & C , id : & str ) -> Result < Self , Self :: Error > ;
384
+
385
+ fn get_sender ( ) -> & ' static dyn Signer ;
350
386
}
351
387
352
388
/// Should be implemented by anything representing an ActivityPub actor.
@@ -385,6 +421,49 @@ pub trait AsActor<C> {
385
421
/// # extern crate activitypub;
386
422
/// # use activitypub::{activity::Create, actor::Person, object::Note};
387
423
/// # use plume_common::activity_pub::inbox::{AsActor, AsObject, FromId};
424
+ /// # use plume_common::activity_pub::sign::{gen_keypair, Error as SignError, Result as SignResult, Signer};
425
+ /// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa};
426
+ /// # use once_cell::sync::Lazy;
427
+ /// #
428
+ /// # static MY_SIGNER: Lazy<MySigner> = Lazy::new(|| MySigner::new());
429
+ /// #
430
+ /// # struct MySigner {
431
+ /// # public_key: String,
432
+ /// # private_key: String,
433
+ /// # }
434
+ /// #
435
+ /// # impl MySigner {
436
+ /// # fn new() -> Self {
437
+ /// # let (pub_key, priv_key) = gen_keypair();
438
+ /// # Self {
439
+ /// # public_key: String::from_utf8(pub_key).unwrap(),
440
+ /// # private_key: String::from_utf8(priv_key).unwrap(),
441
+ /// # }
442
+ /// # }
443
+ /// # }
444
+ /// #
445
+ /// # impl Signer for MySigner {
446
+ /// # fn get_key_id(&self) -> String {
447
+ /// # "mysigner".into()
448
+ /// # }
449
+ /// #
450
+ /// # fn sign(&self, to_sign: &str) -> SignResult<Vec<u8>> {
451
+ /// # let key = PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.as_ref()).unwrap())
452
+ /// # .unwrap();
453
+ /// # let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &key).unwrap();
454
+ /// # signer.update(to_sign.as_bytes()).unwrap();
455
+ /// # signer.sign_to_vec().map_err(|_| SignError())
456
+ /// # }
457
+ /// #
458
+ /// # fn verify(&self, data: &str, signature: &[u8]) -> SignResult<bool> {
459
+ /// # let key = PKey::from_rsa(Rsa::public_key_from_pem(self.public_key.as_ref()).unwrap())
460
+ /// # .unwrap();
461
+ /// # let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &key).unwrap();
462
+ /// # verifier.update(data.as_bytes()).unwrap();
463
+ /// # verifier.verify(&signature).map_err(|_| SignError())
464
+ /// # }
465
+ /// # }
466
+ /// #
388
467
/// # struct Account;
389
468
/// # impl FromId<()> for Account {
390
469
/// # type Error = ();
@@ -397,6 +476,10 @@ pub trait AsActor<C> {
397
476
/// # fn from_activity(_: &(), obj: Person) -> Result<Self, Self::Error> {
398
477
/// # Ok(Account)
399
478
/// # }
479
+ /// #
480
+ /// # fn get_sender() -> &'static dyn Signer {
481
+ /// # &*MY_SIGNER
482
+ /// # }
400
483
/// # }
401
484
/// # impl AsActor<()> for Account {
402
485
/// # fn get_inbox_url(&self) -> String {
@@ -420,6 +503,10 @@ pub trait AsActor<C> {
420
503
/// fn from_activity(_: &(), obj: Note) -> Result<Self, Self::Error> {
421
504
/// Ok(Message { text: obj.object_props.content_string().map_err(|_| ())? })
422
505
/// }
506
+ ///
507
+ /// fn get_sender() -> &'static dyn Signer {
508
+ /// &*MY_SIGNER
509
+ /// }
423
510
/// }
424
511
///
425
512
/// impl AsObject<Account, Create, ()> for Message {
@@ -459,7 +546,51 @@ where
459
546
#[ cfg( test) ]
460
547
mod tests {
461
548
use super :: * ;
549
+ use crate :: activity_pub:: sign:: {
550
+ gen_keypair, Error as SignError , Result as SignResult , Signer ,
551
+ } ;
462
552
use activitypub:: { activity:: * , actor:: Person , object:: Note } ;
553
+ use once_cell:: sync:: Lazy ;
554
+ use openssl:: { hash:: MessageDigest , pkey:: PKey , rsa:: Rsa } ;
555
+
556
+ static MY_SIGNER : Lazy < MySigner > = Lazy :: new ( || MySigner :: new ( ) ) ;
557
+
558
+ struct MySigner {
559
+ public_key : String ,
560
+ private_key : String ,
561
+ }
562
+
563
+ impl MySigner {
564
+ fn new ( ) -> Self {
565
+ let ( pub_key, priv_key) = gen_keypair ( ) ;
566
+ Self {
567
+ public_key : String :: from_utf8 ( pub_key) . unwrap ( ) ,
568
+ private_key : String :: from_utf8 ( priv_key) . unwrap ( ) ,
569
+ }
570
+ }
571
+ }
572
+
573
+ impl Signer for MySigner {
574
+ fn get_key_id ( & self ) -> String {
575
+ "mysigner" . into ( )
576
+ }
577
+
578
+ fn sign ( & self , to_sign : & str ) -> SignResult < Vec < u8 > > {
579
+ let key = PKey :: from_rsa ( Rsa :: private_key_from_pem ( self . private_key . as_ref ( ) ) . unwrap ( ) )
580
+ . unwrap ( ) ;
581
+ let mut signer = openssl:: sign:: Signer :: new ( MessageDigest :: sha256 ( ) , & key) . unwrap ( ) ;
582
+ signer. update ( to_sign. as_bytes ( ) ) . unwrap ( ) ;
583
+ signer. sign_to_vec ( ) . map_err ( |_| SignError ( ) )
584
+ }
585
+
586
+ fn verify ( & self , data : & str , signature : & [ u8 ] ) -> SignResult < bool > {
587
+ let key = PKey :: from_rsa ( Rsa :: public_key_from_pem ( self . public_key . as_ref ( ) ) . unwrap ( ) )
588
+ . unwrap ( ) ;
589
+ let mut verifier = openssl:: sign:: Verifier :: new ( MessageDigest :: sha256 ( ) , & key) . unwrap ( ) ;
590
+ verifier. update ( data. as_bytes ( ) ) . unwrap ( ) ;
591
+ verifier. verify ( & signature) . map_err ( |_| SignError ( ) )
592
+ }
593
+ }
463
594
464
595
struct MyActor ;
465
596
impl FromId < ( ) > for MyActor {
@@ -473,6 +604,10 @@ mod tests {
473
604
fn from_activity ( _: & ( ) , _obj : Person ) -> Result < Self , Self :: Error > {
474
605
Ok ( MyActor )
475
606
}
607
+
608
+ fn get_sender ( ) -> & ' static dyn Signer {
609
+ & * MY_SIGNER
610
+ }
476
611
}
477
612
478
613
impl AsActor < & ( ) > for MyActor {
@@ -497,6 +632,10 @@ mod tests {
497
632
fn from_activity ( _: & ( ) , _obj : Note ) -> Result < Self , Self :: Error > {
498
633
Ok ( MyObject )
499
634
}
635
+
636
+ fn get_sender ( ) -> & ' static dyn Signer {
637
+ & * MY_SIGNER
638
+ }
500
639
}
501
640
impl AsObject < MyActor , Create , & ( ) > for MyObject {
502
641
type Error = ( ) ;
@@ -601,6 +740,10 @@ mod tests {
601
740
fn from_activity ( _: & ( ) , _obj : Person ) -> Result < Self , Self :: Error > {
602
741
Err ( ( ) )
603
742
}
743
+
744
+ fn get_sender ( ) -> & ' static dyn Signer {
745
+ & * MY_SIGNER
746
+ }
604
747
}
605
748
impl AsActor < & ( ) > for FailingActor {
606
749
fn get_inbox_url ( & self ) -> String {
0 commit comments