Signing activities

I hope it works correctly…

Fixes #6
This commit is contained in:
Bat
2018-05-03 20:11:04 +01:00
parent 6b372861d6
commit 22cb286f86
11 changed files with 98 additions and 27 deletions
+32 -3
View File
@@ -1,10 +1,15 @@
use chrono::NaiveDateTime;
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection};
use openssl::hash::MessageDigest;
use openssl::pkey::{PKey, Private};
use openssl::rsa::Rsa;
use openssl::sign::Signer;
use std::sync::Arc;
use activity_pub::activity::Activity;
use activity_pub::actor::{Actor, ActorType};
use activity_pub::outbox::Outbox;
use activity_pub::sign;
use activity_pub::webfinger::*;
use models::instance::Instance;
use schema::blogs;
@@ -20,7 +25,9 @@ pub struct Blog {
pub inbox_url: String,
pub instance_id: i32,
pub creation_date: NaiveDateTime,
pub ap_url: String
pub ap_url: String,
pub private_key: Option<String>,
pub public_key: String
}
#[derive(Insertable)]
@@ -32,7 +39,9 @@ pub struct NewBlog {
pub outbox_url: String,
pub inbox_url: String,
pub instance_id: i32,
pub ap_url: String
pub ap_url: String,
pub private_key: Option<String>,
pub public_key: String
}
impl Blog {
@@ -86,6 +95,10 @@ impl Blog {
fn get_activities(&self, _conn: &PgConnection) -> Vec<Arc<Activity>> {
vec![]
}
pub fn get_keypair(&self) -> PKey<Private> {
PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.clone().unwrap().as_ref()).unwrap()).unwrap()
}
}
impl Actor for Blog {
@@ -149,6 +162,19 @@ impl Webfinger for Blog {
}
}
impl sign::Signer for Blog {
fn get_key_id(&self, conn: &PgConnection) -> String {
format!("{}#main-key", self.compute_id(conn))
}
fn sign(&self, to_sign: String) -> Vec<u8> {
let key = self.get_keypair();
let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
signer.update(to_sign.as_bytes()).unwrap();
signer.sign_to_vec().unwrap()
}
}
impl NewBlog {
pub fn new_local(
actor_id: String,
@@ -156,6 +182,7 @@ impl NewBlog {
summary: String,
instance_id: i32
) -> NewBlog {
let (pub_key, priv_key) = sign::gen_keypair();
NewBlog {
actor_id: actor_id,
title: title,
@@ -163,7 +190,9 @@ impl NewBlog {
outbox_url: String::from(""),
inbox_url: String::from(""),
instance_id: instance_id,
ap_url: String::from("")
ap_url: String::from(""),
public_key: String::from_utf8(pub_key).unwrap(),
private_key: Some(String::from_utf8(priv_key).unwrap())
}
}
}
+15 -12
View File
@@ -5,7 +5,7 @@ use diesel::dsl::any;
use openssl::hash::MessageDigest;
use openssl::pkey::{PKey, Private};
use openssl::rsa::Rsa;
use openssl::sign::Signer;
use openssl::sign;
use reqwest::Client;
use reqwest::header::{Accept, qitem};
use reqwest::mime::Mime;
@@ -20,7 +20,7 @@ use activity_pub::activity::{Create, Activity};
use activity_pub::actor::{ActorType, Actor};
use activity_pub::inbox::Inbox;
use activity_pub::outbox::Outbox;
use activity_pub::sign;
use activity_pub::sign::{Signer, gen_keypair};
use activity_pub::webfinger::{Webfinger, resolve};
use db_conn::DbConn;
use models::follows::Follow;
@@ -263,6 +263,16 @@ impl Actor for User {
ActorType::Person
}
fn custom_props(&self, conn: &PgConnection) -> serde_json::Map<String, serde_json::Value> {
let mut res = serde_json::Map::new();
res.insert("publicKey".to_string(), json!({
"id": self.get_key_id(conn),
"owner": self.compute_id(conn),
"publicKeyPem": self.public_key
}));
res
}
fn from_url(conn: &PgConnection, url: String) -> Option<User> {
let in_db = users::table.filter(users::ap_url.eq(url.clone()))
.limit(1)
@@ -318,14 +328,14 @@ impl Webfinger for User {
}
}
impl sign::Signer for User {
impl Signer for User {
fn get_key_id(&self, conn: &PgConnection) -> String {
format!("{}#main-key", self.compute_id(conn))
}
fn sign(&self, to_sign: String) -> Vec<u8> {
let key = self.get_keypair();
let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
let mut signer = sign::Signer::new(MessageDigest::sha256(), &key).unwrap();
signer.update(to_sign.as_bytes()).unwrap();
signer.sign_to_vec().unwrap()
}
@@ -342,7 +352,7 @@ impl NewUser {
password: String,
instance_id: i32
) -> NewUser {
let (pub_key, priv_key) = NewUser::gen_keypair();
let (pub_key, priv_key) = gen_keypair();
NewUser {
username: username,
display_name: display_name,
@@ -358,11 +368,4 @@ impl NewUser {
private_key: Some(String::from_utf8(priv_key).unwrap())
}
}
// Returns (public key, private key)
fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
let keypair = Rsa::generate(2048).unwrap();
let keypair = PKey::from_rsa(keypair).unwrap();
(keypair.public_key_to_pem().unwrap(), keypair.private_key_to_pem_pkcs8().unwrap())
}
}