1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
// rtj provides a generic job execution framework in Rust
// Copyright 2021 Anthony Martinez
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! **rtj** aims to provide a generic, robust, and secure framework for users to develop
//! their own job execution applications. Encryption uses [`crypto_box`] and is compatible with
//! other implementations of the [standard](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption).
//!
//! ### Example:
//! ```
//! // Full example avaialble in the source repo under /examples/hello.rs
//! use rtj::{Job, Message};
//!# use crypto_box::SecretKey;
//!# use rmp_serde as rmps;
//!# use serde::{Deserialize, Serialize};
//!# type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
//!# enum MsgType {
//!# Hello,
//!# Unknown,
//!# }
//!# impl From<u8> for MsgType {
//!# fn from(t: u8) -> MsgType {
//!# match t {
//!# 0 => MsgType::Hello,
//!# _ => MsgType::Unknown,
//!# }
//!# }
//!# }
//!# impl From<MsgType> for u8 {
//!# fn from(t: MsgType) -> u8 {
//!# match t {
//!# MsgType::Hello => 0,
//!# MsgType::Unknown => 255,
//!# }
//!# }
//!# }
//!# #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
//!# struct Hello {
//!# name: String,
//!# age: u8,
//!# }
//!# impl Job for Hello {
//!# fn encode(&self) -> Vec<u8> {
//!# rmps::to_vec(&self).unwrap()
//!# }
//!# fn decode(input: &[u8]) -> Hello {
//!# let hello: Hello = rmps::from_read(input).unwrap();
//!# hello
//!# }
//!# fn ack(&self) -> Vec<u8> {
//!# let ack_string = format!("Hello from {}, age {}", self.name, self.age);
//!# Vec::from(ack_string)
//!# }
//!# fn run(&self) -> Result<()> {
//!# println!("{}", String::from_utf8(self.ack())?);
//!# Ok(())
//!# }
//!# }
//!# fn main() -> Result<()> {
//!# let mut rng = rand::thread_rng();
//!# // Create the sender's keys
//!# // This would normally be loaded from a secure location
//!# let send_secret = SecretKey::generate(&mut rng);
//!# let send_pub = send_secret.public_key().as_bytes().to_owned();
//!# // Create the recipient's keys
//!# // This would normally exist on a remote node, and be loaded
//!# // from a secure location. The sender should have a copy of
//!# // the remote node's public key to encrypt towards.
//!# let recv_secret = SecretKey::generate(&mut rng);
//!#
//!# let name = "Anthony J. Martinez".to_owned();
//!# let age = 38;
//! // Create a struct that implements Job
//! let hello = Hello { name, age };
//!
//! // Build a Message from that struct
//! let msg = Message::new()
//! .set_payload(&hello)
//! .set_header(MsgType::Hello, send_pub, &mut rng)?;
//!
//! // Encrypt the message payload for the recipient.
//! let encrypted_to_recv = msg.encrypt(recv_secret.public_key(), send_secret)?;
//!
//! // Decrypt the message payload as the recipient.
//! let hello_again = encrypted_to_recv.decrypt(recv_secret)?;
//!
//! // Verify the message type.
//! if let MsgType::Hello = hello_again.header.msgtype.into() {
//! // Deserialize the message payload as the correct type
//! let hello = Hello::decode(&hello_again.payload);
//!
//! // Execute the runner method on the deserialized type
//! hello.run()?;
//! }
//!
//!# Ok(())
//!# }
//! ```
use crypto_box::{
aead::{consts::U24, generic_array::GenericArray, AeadMut},
PublicKey, SecretKey,
};
use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
mod error;
mod header;
mod job;
mod message;
pub use error::RtjError;
pub use header::Header;
pub use job::Job;
pub use message::Message;
type Result<T> = std::result::Result<T, RtjError>;