diff --git a/src/certs.rs b/src/certs.rs
index b7ba444..d70bb9f 100644
--- a/src/certs.rs
+++ b/src/certs.rs
@@ -3,7 +3,8 @@ use anyhow::{anyhow, Context, Result};
 use std::{path::PathBuf, sync::Arc};
 
 use crate::common::{is_file_exist, read_file, write_file, AppConfig, OpenSSLProviderArg, VarsMap};
-use crate::crypto::{ICryptoProvider, OpenSSLExternalProvider, OpenSSLInternalProvider};
+use crate::crypto_provider::ICryptoProvider;
+use crate::openssl::{external::OpenSSLExternalProvider, internal::OpenSSLInternalProvider};
 
 pub(crate) struct Certs<T>
 where
diff --git a/src/crypto_provider.rs b/src/crypto_provider.rs
new file mode 100644
index 0000000..afb2a96
--- /dev/null
+++ b/src/crypto_provider.rs
@@ -0,0 +1,6 @@
+use anyhow::Result;
+
+pub(crate) trait ICryptoProvider {
+    async fn request(&self) -> Result<()>;
+    async fn sign(&self) -> Result<()>;
+}
diff --git a/src/main.rs b/src/main.rs
index 9d621b2..2c135bd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,7 +3,8 @@ use clap::Parser;
 
 mod certs;
 mod common;
-mod crypto;
+mod crypto_provider;
+mod openssl;
 mod vars;
 
 use crate::certs::build_client_config;
diff --git a/src/openssl/external.rs b/src/openssl/external.rs
new file mode 100644
index 0000000..b54da1b
--- /dev/null
+++ b/src/openssl/external.rs
@@ -0,0 +1,138 @@
+use anyhow::{anyhow, Result};
+use std::path::PathBuf;
+
+use tokio::process::Command;
+
+use crate::common::{is_file_exist, AppConfig, VarsMap};
+use crate::crypto_provider::ICryptoProvider;
+
+pub(crate) struct OpenSSLExternalProvider {
+    vars: VarsMap,
+    base_dir: PathBuf,
+    openssl_cnf: PathBuf,
+    openssl: String,
+    ca_file: PathBuf,
+    req_file: PathBuf,
+    key_file: PathBuf,
+    cert_file: PathBuf,
+    req_days: u32,
+}
+
+impl OpenSSLExternalProvider {
+    async fn is_ca_exists(&self) -> bool {
+        is_file_exist(&self.ca_file).await
+    }
+
+    async fn is_cert_exists(&self) -> bool {
+        is_file_exist(&self.cert_file).await
+    }
+
+    async fn is_req_exists(&self) -> bool {
+        is_file_exist(&self.req_file).await
+    }
+
+    pub(crate) fn from_cfg(cfg: &AppConfig, vars: VarsMap) -> Self {
+        let base_dir = PathBuf::from(&cfg.base_directory);
+        let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone());
+        let name = cfg.name.clone();
+        let mut vars = vars;
+
+        vars.insert("KEY_CN".into(), name.clone());
+        vars.insert("KEY_NAME".into(), name.clone());
+        vars.insert("KEY_EMAIL".into(), cfg.email.clone());
+
+        let ca_file = keys_dir.join(cfg.ca_filename.clone());
+        let req_file = keys_dir.join(format!("{}.csr", &name));
+        let key_file = keys_dir.join(format!("{}.key", &name));
+        let cert_file = keys_dir.join(format!("{}.crt", &name));
+        let openssl_cnf = base_dir.clone().join(
+            std::env::var(cfg.openssl_cnf_env.clone()).unwrap_or(cfg.openssl_default_cnf.clone()),
+        );
+
+        Self {
+            vars,
+            base_dir,
+            openssl_cnf,
+            openssl: cfg.openssl.to_string(),
+            ca_file,
+            req_file,
+            key_file,
+            cert_file,
+            req_days: cfg.req_days,
+        }
+    }
+}
+
+impl ICryptoProvider for OpenSSLExternalProvider {
+    async fn request(&self) -> Result<()> {
+        if self.is_req_exists().await {
+            return Ok(());
+        }
+
+        if !self.is_ca_exists().await {
+            return Err(anyhow!(
+                "ca file not found: {}",
+                &self.ca_file.to_str().unwrap()
+            ));
+        }
+
+        let status = Command::new(&self.openssl)
+            .args([
+                "req",
+                "-nodes",
+                "-new",
+                "-keyout",
+                self.key_file.to_str().unwrap(),
+                "-out",
+                self.req_file.to_str().unwrap(),
+                "-config",
+                self.openssl_cnf.to_str().unwrap(),
+                "-batch",
+            ])
+            .current_dir(&self.base_dir)
+            .envs(&self.vars)
+            .status()
+            .await?;
+
+        match status.success() {
+            true => Ok(()),
+            false => Err(anyhow!("openssl req execution failed")),
+        }
+    }
+
+    async fn sign(&self) -> Result<()> {
+        if self.is_cert_exists().await {
+            return Ok(());
+        }
+
+        if !self.is_ca_exists().await {
+            return Err(anyhow!(
+                "ca file not found: {}",
+                &self.ca_file.to_str().unwrap()
+            ));
+        }
+
+        let status = Command::new(&self.openssl)
+            .args([
+                "ca",
+                "-days",
+                format!("{}", self.req_days).as_str(),
+                "-out",
+                self.cert_file.to_str().unwrap(),
+                "-in",
+                self.req_file.to_str().unwrap(),
+                "-config",
+                self.openssl_cnf.to_str().unwrap(),
+                "-batch",
+            ])
+            .current_dir(&self.base_dir)
+            .envs(&self.vars)
+            .status()
+            .await?;
+
+        match status.success() {
+            true => Ok(()),
+            false => Err(anyhow!("ssl ca execution failed")),
+        }
+    }
+}
diff --git a/src/crypto.rs b/src/openssl/internal.rs
similarity index 73%
rename from src/crypto.rs
rename to src/openssl/internal.rs
index 2e6174a..02f2418 100644
--- a/src/crypto.rs
+++ b/src/openssl/internal.rs
@@ -13,9 +13,12 @@ use openssl::{
 };
 use std::path::{Path, PathBuf};
 
-use tokio::{fs, process::Command};
+use tokio::fs;
 
-use crate::common::{is_file_exist, read_file, AppConfig, VarsMap};
+use crate::{
+    common::{is_file_exist, read_file, AppConfig, VarsMap},
+    crypto_provider::ICryptoProvider,
+};
 
 use lazy_static::lazy_static;
 use std::collections::HashMap;
@@ -88,142 +91,6 @@ fn get_time_str_x509(days: u32) -> Result<String> {
     Ok(s)
 }
 
-pub(crate) trait ICryptoProvider {
-    async fn request(&self) -> Result<()>;
-    async fn sign(&self) -> Result<()>;
-}
-
-pub(crate) struct OpenSSLExternalProvider {
-    vars: VarsMap,
-    base_dir: PathBuf,
-    openssl_cnf: PathBuf,
-    openssl: String,
-    ca_file: PathBuf,
-    req_file: PathBuf,
-    key_file: PathBuf,
-    cert_file: PathBuf,
-    req_days: u32,
-}
-
-impl OpenSSLExternalProvider {
-    async fn is_ca_exists(&self) -> bool {
-        is_file_exist(&self.ca_file).await
-    }
-
-    async fn is_cert_exists(&self) -> bool {
-        is_file_exist(&self.cert_file).await
-    }
-
-    async fn is_req_exists(&self) -> bool {
-        is_file_exist(&self.req_file).await
-    }
-
-    pub(crate) fn from_cfg(cfg: &AppConfig, vars: VarsMap) -> Self {
-        let base_dir = PathBuf::from(&cfg.base_directory);
-        let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone());
-        let name = cfg.name.clone();
-        let mut vars = vars;
-
-        vars.insert("KEY_CN".into(), name.clone());
-        vars.insert("KEY_NAME".into(), name.clone());
-        vars.insert("KEY_EMAIL".into(), cfg.email.clone());
-
-        let ca_file = keys_dir.join(cfg.ca_filename.clone());
-        let req_file = keys_dir.join(format!("{}.csr", &name));
-        let key_file = keys_dir.join(format!("{}.key", &name));
-        let cert_file = keys_dir.join(format!("{}.crt", &name));
-        let openssl_cnf = base_dir.clone().join(
-            std::env::var(cfg.openssl_cnf_env.clone()).unwrap_or(cfg.openssl_default_cnf.clone()),
-        );
-
-        Self {
-            vars,
-            base_dir,
-            openssl_cnf,
-            openssl: cfg.openssl.to_string(),
-            ca_file,
-            req_file,
-            key_file,
-            cert_file,
-            req_days: cfg.req_days,
-        }
-    }
-}
-
-impl ICryptoProvider for OpenSSLExternalProvider {
-    async fn request(&self) -> Result<()> {
-        if self.is_req_exists().await {
-            return Ok(());
-        }
-
-        if !self.is_ca_exists().await {
-            return Err(anyhow!(
-                "ca file not found: {}",
-                &self.ca_file.to_str().unwrap()
-            ));
-        }
-
-        let status = Command::new(&self.openssl)
-            .args([
-                "req",
-                "-nodes",
-                "-new",
-                "-keyout",
-                self.key_file.to_str().unwrap(),
-                "-out",
-                self.req_file.to_str().unwrap(),
-                "-config",
-                self.openssl_cnf.to_str().unwrap(),
-                "-batch",
-            ])
-            .current_dir(&self.base_dir)
-            .envs(&self.vars)
-            .status()
-            .await?;
-
-        match status.success() {
-            true => Ok(()),
-            false => Err(anyhow!("openssl req execution failed")),
-        }
-    }
-
-    async fn sign(&self) -> Result<()> {
-        if self.is_cert_exists().await {
-            return Ok(());
-        }
-
-        if !self.is_ca_exists().await {
-            return Err(anyhow!(
-                "ca file not found: {}",
-                &self.ca_file.to_str().unwrap()
-            ));
-        }
-
-        let status = Command::new(&self.openssl)
-            .args([
-                "ca",
-                "-days",
-                format!("{}", self.req_days).as_str(),
-                "-out",
-                self.cert_file.to_str().unwrap(),
-                "-in",
-                self.req_file.to_str().unwrap(),
-                "-config",
-                self.openssl_cnf.to_str().unwrap(),
-                "-batch",
-            ])
-            .current_dir(&self.base_dir)
-            .envs(&self.vars)
-            .status()
-            .await?;
-
-        match status.success() {
-            true => Ok(()),
-            false => Err(anyhow!("ssl ca execution failed")),
-        }
-    }
-}
-
 pub(crate) struct OpenSSLInternalProvider {
     vars: VarsMap,
     #[allow(unused)]
diff --git a/src/openssl/mod.rs b/src/openssl/mod.rs
new file mode 100644
index 0000000..d29baed
--- /dev/null
+++ b/src/openssl/mod.rs
@@ -0,0 +1,2 @@
+pub(crate) mod external;
+pub(crate) mod internal;