crypto_ext/
lib.rs

1//! # crypto-ext
2//!
3//! `crypto-ext` is a set of functionality providing easy and intuitive abstractions to encrypt, decrypt, sign and verify your data.
4//!
5//! ## Features
6//! 1. [Asymmetric cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography) via [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem))
7//! 1. [Symmetric cryptography](https://en.wikipedia.org/wiki/Symmetric-key_algorithm) via [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
8//! 1. [Digital signature](https://en.wikipedia.org/wiki/Digital_signature) via [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
9//! 1. [Passphrase](https://en.wikipedia.org/wiki/Passphrase)
10
11
12use std::env;
13use std::fs::{File, OpenOptions};
14use std::io::{Read, Write};
15use std::path::Path;
16
17pub mod asymmetric;
18pub mod symmetric;
19pub mod passphrase;
20
21// below are functions not exposed as an api, used for inner implementation
22
23fn get_static_filepath(path: &str) -> Result<String, String> {
24    let boxed_dir = env::current_dir();
25    if boxed_dir.is_err() {
26        let error = boxed_dir.err().unwrap();
27        eprintln!("{}", error);
28        return Err(error.to_string());
29    }
30    let dir = boxed_dir.unwrap();
31
32
33    let boxed_working_directory = dir.as_path().to_str();
34    if boxed_working_directory.is_none() {
35        let error = "working directory is not set";
36        eprintln!("{}", error);
37        return Err(error.to_string());
38    }
39
40    let working_directory = boxed_working_directory.unwrap();
41    let absolute_path = [working_directory, path].join("");
42    Ok(absolute_path)
43}
44
45fn get_path_relative_to_working_directory(boxed_path_to_encryption_parameters: Option<&str>, filename: &str) -> String {
46    if boxed_path_to_encryption_parameters.is_some() {
47        let path_to_encryption_parameters = boxed_path_to_encryption_parameters.unwrap();
48        return [path_to_encryption_parameters, filename].join("");
49    }
50
51    filename.to_string()
52}
53
54
55fn read_or_create_and_write(path: &str, content: &[u8]) -> Result<Vec<u8>, String> {
56    let does_passphrase_exist = does_file_exist(path);
57    return if does_passphrase_exist {
58        let boxed_read = read_file(path);
59        if boxed_read.is_err() {
60            return Err(boxed_read.err().unwrap());
61        }
62        let passphrase = boxed_read.unwrap();
63        Ok(passphrase)
64    } else {
65        let boxed_create = create_file(path);
66        if boxed_create.is_err() {
67            let message = boxed_create.err().unwrap();
68            return Err(message)
69        }
70
71        let boxed_write = write_file(path, content);
72        if boxed_write.is_err() {
73            let message = boxed_write.err().unwrap();
74            return Err(message)
75        }
76        Ok(Vec::from(content))
77    }
78}
79
80fn create_file(path: &str) -> Result<File, String>  {
81    let boxed_file = File::create(path);
82
83    if boxed_file.is_err() {
84        let message = format!("unable to create file: {}", boxed_file.err().unwrap());
85        return Err(message)
86    }
87
88    let file = boxed_file.unwrap();
89    Ok(file)
90}
91
92fn does_file_exist(path: &str) -> bool {
93    let file_exists = Path::new(path).is_file();
94    file_exists
95}
96
97fn read_file(path: &str) -> Result<Vec<u8>, String> {
98    let mut file_contents : Vec<u8> = vec![];
99    let boxed_open = OpenOptions::new()
100        .read(true)
101        .write(false)
102        .create(false)
103        .truncate(false)
104        .open(path);
105    if boxed_open.is_err() {
106        let message = format!("unable to read from file: {}", boxed_open.err().unwrap());
107        return Err(message)
108    }
109
110    let mut file = boxed_open.unwrap();
111
112    let boxed_read = file.read_to_end(&mut file_contents);
113    if boxed_read.is_err() {
114        let message = format!("unable to read from file: {}", boxed_read.err().unwrap());
115        return Err(message)
116    }
117
118    Ok(file_contents)
119}
120
121fn write_file(path: &str, file_content: &[u8]) -> Result<(), String> {
122    let mut file = OpenOptions::new()
123        .read(false)
124        .write(true)
125        .create(false)
126        .truncate(false)
127        .open(path)
128        .unwrap();
129    let boxed_write = file.write_all(file_content);
130    if boxed_write.is_err() {
131        let message = format!("unable to write to file: {}", boxed_write.err().unwrap());
132        return Err(message)
133    }
134    Ok(())
135}