easy_ssl/
lib.rs

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            //***************************************************
58            //rsa keys to PEM
59
60            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            //***************************************************
82            //rsa to pKeyRef
83
84            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            //***************************************************
107            //make x509 cert
108
109            //let mut x509 = openssl::x509::X509::builder().unwrap();
110
111            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        //println!("build : {:?}",build);
298
299        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}