1use openssl;
2use openssl::pkey::PKey;
3use openssl::hash::MessageDigest;
4use openssl::asn1::Asn1Time;
5
6use std::io::prelude::*;
7use std::fs::File;
8
9pub mod issuer;
10pub mod subject;
11pub mod common;
12pub mod builder;
13
14use builder::Builder;
15
16#[derive(Debug, Clone)]
17pub struct Generated {
18 pub cert:Vec<u8>,
19 pub key:Vec<u8>
20}
21
22pub fn generate_as_files(config:&mut builder::Builder) -> Result<(),String> {
23
24 match generate_as_vec(config) {
25 Ok(r)=>{
26
27 match make_file(config.certificate_path.clone(),r.cert) {
28 Ok(_)=>{},
29 Err(_)=>{
30 return Err(common::error("failed to write x509 certificate"));
31 }
32 }
33
34 match make_file(config.key_path.clone(),r.key) {
35 Ok(_)=>{},
36 Err(_)=>{
37 return Err(common::error("failed to write rsa private key"));
38 }
39 }
40
41 return Ok(());
42
43 },
44 Err(e)=>{
45 println!("error : {:}",e);
46 return Err(common::error("failed-generate_as_vec-generate_as_files"));
47 }
48 }
49
50}
51
52pub fn generate_as_vec(config:&mut builder::Builder) -> Result<Generated,String> {
53
54 match openssl::rsa::Rsa::generate(config.key_size) {
55 Ok(keys)=> {
56
57 let private_key_as_u8_vec;
61 match keys.private_key_to_pem() {
62 Ok(r)=>{
63 private_key_as_u8_vec = r;
64 },
65 Err(_) => {
66 return Err(common::error("failed to create private key vector"));
67 }
68 }
69
70 let public_key_as_u8_vec;
71 match keys.public_key_to_pem() {
72 Ok(r)=>{
73 public_key_as_u8_vec = r;
74 },
75 Err(e) => {
76 println!("error : {:?}",e);
77 return Err(common::error("failed to create public key vector"));
78 }
79 }
80
81 let public_key_ref;
85 match PKey::public_key_from_pem(&public_key_as_u8_vec) {
86 Ok(r)=>{
87 public_key_ref = r;
88 },
89 Err(e)=>{
90 println!("error : {:?}",e);
91 return Err(common::error("failed to create public key ref"));
92 }
93 }
94
95 let private_key_ref;
96 match PKey::private_key_from_pem(&private_key_as_u8_vec) {
97 Ok(r)=>{
98 private_key_ref = r;
99 },
100 Err(e)=>{
101 println!("error : {:?}",e);
102 return Err(common::error("failed to create public key ref"));
103 }
104 }
105
106 let mut x509;
112 match openssl::x509::X509::builder() {
113 Ok(r)=>{
114 x509 = r;
115 },
116 Err(e)=>{
117 println!("error : {:?}",e);
118 return Err(common::error("failed-initiate-x509Builder"));
119 }
120 }
121
122 match x509.set_pubkey(&public_key_ref) {
123 Ok(_)=>{},
124 Err(e)=>{
125 println!("error : {:?}",e);
126 return Err(common::error("failed-set_sub_key"));
127 }
128 }
129
130 match openssl::x509::X509NameBuilder::new() {
131 Ok(mut x509_name)=>{
132 let map = config.subject.to_hash_map();
133 for (key, val) in map.iter() {
134 match x509_name.append_entry_by_text(key, val) {
135 Ok(_)=>{},
136 Err(e)=>{
137 println!("error : {:?}",e);
138 println!("key : {:?} , val : {:?}",key,val);
139 return Err(common::error("failed-set_subject_row"));
140 }
141 }
142 }
143 let x509_name = x509_name.build();
144 match x509.set_subject_name(&x509_name) {
145 Ok(_)=>{},
146 Err(_)=>{
147 return Err(common::error("failed to set x509_name"));
148 }
149 }
150 },
151 Err(_)=>{
152 return Err(common::error("failed to initiate name builder for x509_name"));
153 }
154 }
155
156 match openssl::x509::X509NameBuilder::new() {
157 Ok(mut x509_issuer)=>{
158 let map = config.issuer.to_hash_map();
159 for (key, val) in map.iter() {
160 match x509_issuer.append_entry_by_text(key, val) {
161 Ok(_)=>{},
162 Err(e)=>{
163 println!("error : {:?}",e);
164 println!("key : {:?} , val : {:?}",key,val);
165 return Err(common::error("failed-set_issuer_row"));
166 }
167 }
168 }
169 let x509_issuer = x509_issuer.build();
170 match x509.set_issuer_name(&x509_issuer) {
171 Ok(_)=>{},
172 Err(_)=>{
173 return Err(common::error("failed to set x509_issuer"));
174 }
175 }
176 },
177 Err(_)=>{
178 return Err(common::error("failed to initiate name builder for x509_issuer"));
179 }
180 }
181
182 match Asn1Time::days_from_now(365) {
183 Ok(r)=>{
184 match x509.set_not_after(&r) {
185 Ok(_)=>{},
186 Err(e)=>{
187 println!("error : {:?}",e);
188 return Err(common::error("failed-set-Asn1Time_expiry_date"));
189 }
190 }
191 },
192 Err(e)=>{
193 println!("error : {:?}",e);
194 return Err(common::error("failed-get-Asn1Time_expiry_date"));
195 }
196 }
197
198 match Asn1Time::days_from_now(0) {
199 Ok(r)=>{
200 match x509.set_not_before(&r) {
201 Ok(_)=>{},
202 Err(e)=>{
203 println!("error : {:?}",e);
204 return Err(common::error("failed-set-Asn1Time_start_date"));
205 }
206 }
207 },
208 Err(e)=>{
209 println!("error : {:?}",e);
210 return Err(common::error("failed-get-Asn1Time_start_date"));
211 }
212 }
213
214 if true {
215 match x509.sign(&private_key_ref,MessageDigest::sha512()) {
216 Ok(_)=>{},
217 Err(e)=>{
218 println!("!!! : {:?}",e);
219 return Err(common::error("failed to sign x509 certificate"));
220 }
221 }
222 }
223
224 let x509_cert = x509.build();
225
226 let certificate_as_u8_vec;
227 match x509_cert.to_pem() {
228 Ok(r)=>{
229 certificate_as_u8_vec = r;
230 },
231 Err(_)=>{
232 return Err(common::error("failed to parse x509 certificate to u8 vector"));
233 }
234 }
235
236 let result = Generated {
237 cert:certificate_as_u8_vec,
238 key:private_key_as_u8_vec
239 };
240
241 return Ok(result);
242
243 },
244 Err(e) => {
245 println!("error : {:?}",e);
246 return Err(common::error("failed to create rsa keys"));
247 }
248 }
249
250}
251
252fn make_file(path:String,data:Vec<u8>) -> Result<(),String> {
253
254 match File::create(&path) {
255 Ok(mut r) => {
256 match r.write(&data) {
257 Ok(_)=>{
258 return Ok(());
259 },
260 Err(e)=>{
261 return Err(common::error_string(format!("!!! failed - write to file at => {:?} , Error => {:?}",&path,e)));
262 }
263 }
264 },
265 Err(e) => {
266 return Err(common::error_string(format!("!!! failed - create to file at => {:?} , Error => {:?}",&path,e)));
267 }
268 }
269
270}
271
272#[cfg(test)]
273mod test {
274 use crate;
275
276 #[test]
277 fn test(){
278
279 let mut build = Builder::new();
280
281 build.set_key_path("D://workstation/expo/rust/fdb/cert/keys/key.pem".to_string());
282 build.set_certificate_path("D://workstation/expo/rust/fdb/cert/keys/cert.pem".to_string());
283 build.set_key_size(4048);
284
285 build.issuer.set_country("IN".to_string());
286 build.issuer.set_state("UP".to_string());
287 build.issuer.set_location("GZB".to_string());
288 build.issuer.set_org("DAACHI".to_string());
289 build.issuer.set_common_name("https://daachi.in".to_string());
290
291 build.subject.set_country("IN".to_string());
292 build.subject.set_state("UP".to_string());
293 build.subject.set_location("GZB".to_string());
294 build.subject.set_org("DAACHI".to_string());
295 build.subject.set_common_name("127.0.0.1".to_string());
296
297 match generate_as_files(&mut build) {
300 Ok(_)=>{
301 common::log("ssl files created successfully");
302 },
303 Err(_)=>{
304 common::error("failed to create ssl files");
305 }
306 }
307
308 }
309
310}