feat(project):放置全新的项目结构。

This commit is contained in:
徐涛
2024-04-01 14:51:43 +08:00
commit 2a65387ddc
25 changed files with 804 additions and 0 deletions

11
cert_lib/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "cert_lib"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.81"
openssl = "0.10.64"
thiserror = "1.0.58"

9
cert_lib/src/errors.rs Normal file
View File

@@ -0,0 +1,9 @@
use thiserror::Error;
#[derive(Debug, Error)]
pub enum CertificateGenerateError {
#[error("Error generating RSA key")]
X509Error(#[from] openssl::error::ErrorStack),
#[error("IO Error")]
IOError(#[from] std::io::Error),
}

101
cert_lib/src/lib.rs Normal file
View File

@@ -0,0 +1,101 @@
use std::fs::{self, File};
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::{io, path::Path};
use openssl::bn::BigNumContext;
use openssl::x509::X509;
use openssl::{
asn1::{Asn1Integer, Asn1Time},
bn::BigNum,
pkey::PKey,
rsa::Rsa,
x509::X509Builder,
};
pub mod errors;
mod root_certificate;
/// 生成证书,公钥保存为.pem文件私钥保存为.key文件
///
/// - `storage_path`:证书存储路径
/// - `certificate_name`:证书名称
/// - `key_length`:密钥长度
/// - `available_days`:证书有效天数
/// - `version`:证书版本
/// - `serial_number`证书序列号如果不设定则默认为1
pub fn generate_certificate(
storage_path: &str,
certificate_name: &str,
key_length: u32,
available_days: u32,
version: i32,
serial_number: Option<u32>,
) -> anyhow::Result<()> {
let rsa = Rsa::generate(key_length)?;
let private_key = rsa.private_key_to_pem()?;
let mut builder = X509Builder::new()?;
builder.set_version(version)?;
let pkey = PKey::from_rsa(rsa)?;
builder.set_pubkey(&pkey)?;
let not_before = Asn1Time::days_from_now(0)?;
let not_after = Asn1Time::days_from_now(available_days)?;
builder.set_not_before(&not_before)?;
builder.set_not_after(&not_after)?;
let serial_number = BigNum::from_u32(serial_number.unwrap_or(1))?;
let sn = Asn1Integer::from_bn(&serial_number)?;
builder.set_serial_number(&sn)?;
let certificate = builder.build();
let store_path = PathBuf::from(storage_path);
ensure_path_exists(&store_path).unwrap();
let cert_path = store_path.clone().join(format!("{}.pem", certificate_name));
let cert_file = File::create(cert_path)?;
let mut writer = BufWriter::new(cert_file);
writer.write_all(&certificate.to_pem()?)?;
writer.flush()?;
let private_key_path = store_path.join(format!("{}.key", certificate_name));
let private_key_file = File::create(private_key_path)?;
let mut writer = BufWriter::new(private_key_file);
writer.write_all(&private_key)?;
writer.flush()?;
Ok(())
}
/// 确保指定路径存在,如果不存在则创建
///
/// - `target_path`:目标路径
fn ensure_path_exists<P: AsRef<Path>>(target_path: P) -> Result<(), io::Error> {
let path = target_path.as_ref();
if !path.exists() {
fs::create_dir_all(path)?;
}
Ok(())
}
/// 计算用于net-filter中power插件中Equal所使用的值。
pub fn calculate_power_euqal_result(cert: X509) -> anyhow::Result<String> {
let x = BigNum::from_slice(cert.signature().as_slice())?;
let y = BigNum::from_u32(65537)?;
let root_cert_pub_key = root_certificate::x509_certificate()?.public_key()?.rsa()?;
let z = root_cert_pub_key.n();
let cert_pub_key = cert.public_key()?.rsa()?;
let n = cert_pub_key.n();
let mut ctx = BigNumContext::new()?;
let mut result = BigNum::new()?;
result.mod_exp(&x, &y, &n, &mut ctx)?;
Ok(format!(
"EQUAL,{},{},{}->{}",
x.to_dec_str()?,
y.to_dec_str()?,
z.to_dec_str()?,
result.to_dec_str()?
))
}

View File

@@ -0,0 +1,42 @@
use openssl::{error::ErrorStack, x509::X509};
/// 根证书内容。
fn certificate() -> String {
String::from(
r#"-----BEGIN CERTIFICATE-----
MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2
WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYG
y+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBl
m5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNX
EpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8bo
iwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVA
xoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOw
jzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52F
LcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXr
SopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZM
Q9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXR
Rus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEA
AaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEw
P4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2Zp
bGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq
hkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpK
BMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7o
uLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6
hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlL
S9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+n
fDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPk
X+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn
8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB
/gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me
0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujl
FeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU=
-----END CERTIFICATE-----"#,
)
}
/// 获取x509格式根证书。
pub fn x509_certificate() -> Result<X509, ErrorStack> {
X509::from_pem(certificate().as_bytes())
}