[core] RA no more panic (#193)

diff --git a/mesatee_core/src/lib.rs b/mesatee_core/src/lib.rs
index 13ce757..f9f22e9 100644
--- a/mesatee_core/src/lib.rs
+++ b/mesatee_core/src/lib.rs
@@ -71,7 +71,7 @@
         error!("Runtime config is not initialized");
         return Err(Error::from(ErrorKind::ECallError));
     }
-    crate::rpc::sgx::prelude();
+    crate::rpc::sgx::prelude()?;
 
     Ok(())
 }
diff --git a/mesatee_core/src/rpc/sgx/client.rs b/mesatee_core/src/rpc/sgx/client.rs
index 9e408e6..9c484b1 100644
--- a/mesatee_core/src/rpc/sgx/client.rs
+++ b/mesatee_core/src/rpc/sgx/client.rs
@@ -35,6 +35,9 @@
         { RwLock::new(ClientConfigCache::default()) };
 }
 
+// We use sha256 of private_key as the identity of current enclave.
+// The config cache is organized by a hashmap, in which the target
+// enclave_attr is the key.
 #[cfg(feature = "mesalock_sgx")]
 #[derive(Default)]
 struct ClientConfigCache {
@@ -50,21 +53,18 @@
 
 #[cfg(feature = "mesalock_sgx")]
 pub(crate) fn get_tls_config(server_attr: Arc<EnclaveAttr>) -> Arc<rustls::ClientConfig> {
-    use crate::rpc::sgx::ra::get_ra_cert;
+    use crate::rpc::sgx::ra::get_current_ra_credential;
 
-    // To re-use existing TLS cache, we need to first check if the server has
-    // updated his RA cert
-    let cert_key = get_ra_cert();
+    let ra_credential = get_current_ra_credential();
 
-    // TODO: add wrapper function
     if let Ok(cfg_cache) = CLIENT_CONFIG_CACHE.try_read() {
         if let Some(cfg) = cfg_cache.target_configs.get(&server_attr) {
             return cfg.clone();
         }
     }
 
-    let certs = vec![rustls::Certificate(cert_key.cert)];
-    let privkey = rustls::PrivateKey(cert_key.private_key);
+    let certs = vec![rustls::Certificate(ra_credential.cert)];
+    let privkey = rustls::PrivateKey(ra_credential.private_key);
 
     let mut client_cfg = rustls::ClientConfig::new();
     client_cfg.set_single_client_cert(certs, privkey);
@@ -76,11 +76,10 @@
 
     let final_arc = Arc::new(client_cfg);
 
-    // TODO: add wrapper function
     if let Ok(mut cfg_cache) = CLIENT_CONFIG_CACHE.try_write() {
-        if cfg_cache.private_key_sha256 != cert_key.private_key_sha256 {
+        if cfg_cache.private_key_sha256 != ra_credential.private_key_sha256 {
             *cfg_cache = ClientConfigCache {
-                private_key_sha256: cert_key.private_key_sha256,
+                private_key_sha256: ra_credential.private_key_sha256,
                 target_configs: HashMap::new(),
             }
         }
@@ -95,8 +94,6 @@
 
 #[cfg(not(feature = "mesalock_sgx"))]
 pub(crate) fn get_tls_config(server_attr: Arc<EnclaveAttr>) -> Arc<rustls::ClientConfig> {
-    // We believe a client from untrusted side do not change his tls cert
-    // during single execution.
     if let Ok(cfg_cache) = CLIENT_CONFIG_CACHE.try_read() {
         if let Some(cfg) = cfg_cache.target_configs.get(&server_attr) {
             return cfg.clone();
diff --git a/mesatee_core/src/rpc/sgx/mod.rs b/mesatee_core/src/rpc/sgx/mod.rs
index f6b45ff..7c46da5 100644
--- a/mesatee_core/src/rpc/sgx/mod.rs
+++ b/mesatee_core/src/rpc/sgx/mod.rs
@@ -55,8 +55,10 @@
 
 // Export this function for sgx enclave initialization
 #[cfg(feature = "mesalock_sgx")]
-pub fn prelude() {
-    ra::get_ra_cert();
+pub fn prelude() -> Result<()> {
+    // Hard coded RACredential validity in seconds for all enclave.
+    // We may allow each enclave to setup its own validity in the future.
+    ra::init_ra_credential(86400u64)
 }
 
 #[derive(Clone)]
diff --git a/mesatee_core/src/rpc/sgx/ra.rs b/mesatee_core/src/rpc/sgx/ra.rs
index c0b7f84..c94da09 100644
--- a/mesatee_core/src/rpc/sgx/ra.rs
+++ b/mesatee_core/src/rpc/sgx/ra.rs
@@ -40,7 +40,7 @@
 use std::net::TcpStream;
 use std::ptr;
 use std::sync::{Arc, SgxRwLock};
-use std::time::SystemTime;
+use std::time::{self, SystemTime};
 use std::untrusted::time::SystemTimeEx;
 
 use lazy_static::lazy_static;
@@ -83,59 +83,12 @@
     ) -> sgx_status_t;
 }
 
-/// Certificate and public key in DER format
-#[derive(Clone, Hash)]
-pub(crate) struct CertKeyPair {
-    pub cert: Vec<u8>,
-    pub private_key: Vec<u8>,
-    pub private_key_sha256: sgx_sha256_hash_t,
-}
-
-impl CertKeyPair {
-    fn new() -> Result<CertKeyPair> {
-        let cert_key_pair = mayfail! {
-            let ecc_handle = SgxEccHandle::new();
-            _open_result =<< ecc_handle.open();
-            (prv_k, pub_k) =<< ecc_handle.create_key_pair();
-            _close_result =<< ecc_handle.close();
-
-            AttnReport {
-                report: attn_report,
-                signature: sig,
-                certificate: cert,
-            } =<< create_attestation_report(&pub_k);
-            let payload = [attn_report, sig, cert].join("|");
-
-            let key_pair = Secp256k1KeyPair::new(prv_k, pub_k);
-            let cert_der = key_pair.create_cert_with_extension("Teaclave", "Teaclave", &payload.as_bytes());
-            let prv_key_der = key_pair.private_key_into_der();
-            sha256 =<< rsgx_sha256_slice(&prv_key_der);
-            ret CertKeyPair {
-                cert: cert_der,
-                private_key: prv_key_der,
-                private_key_sha256: sha256
-            }
-        }?;
-
-        Ok(cert_key_pair)
-    }
-}
-
-#[derive(Clone)]
-struct RACache {
-    cert_key: CertKeyPair,
-    gen_time: SystemTime,
-}
-
 lazy_static! {
     static ref RACACHE: SgxRwLock<RACache> = {
         SgxRwLock::new(RACache {
-            cert_key: CertKeyPair {
-                cert: Vec::<u8>::new(),
-                private_key: Vec::<u8>::new(),
-                private_key_sha256: sgx_sha256_hash_t::default(),
-            },
+            ra_credential: RACredential::default(),
             gen_time: SystemTime::UNIX_EPOCH,
+            validity: time::Duration::from_secs(0),
         })
     };
 
@@ -151,6 +104,290 @@
     };
 }
 
+/// Certificate and public key in DER format
+#[derive(Clone, Hash, Default)]
+pub(crate) struct RACredential {
+    pub cert: Vec<u8>,
+    pub private_key: Vec<u8>,
+    pub private_key_sha256: sgx_sha256_hash_t,
+}
+
+#[derive(Clone)]
+struct RACache {
+    ra_credential: RACredential,
+    gen_time: SystemTime,
+    validity: time::Duration,
+}
+
+struct Secp256k1KeyPair {
+    prv_k: sgx_ec256_private_t,
+    pub_k: sgx_ec256_public_t,
+}
+
+pub(crate) fn init_ra_credential(valid_secs: u64) -> Result<()> {
+    match RACache::new(valid_secs) {
+        Ok(new_entry) => {
+            *RACACHE.write().unwrap() = new_entry;
+            Ok(())
+        }
+        Err(e) => {
+            error!("Cannot initialize RACredential: {:?}", e);
+            Err(Error::from(ErrorKind::RAInternalError))
+        }
+    }
+}
+
+pub(crate) fn get_current_ra_credential() -> RACredential {
+    // Check if the global cert valid
+    // If valid, use it directly
+    // If invalid, update it before use.
+    // Generate Keypair
+
+    // 1. Check if the global cert valid
+    //    Need block read here. It should wait for writers to complete
+    {
+        // Unwrapping failing means the RwLock is poisoned.
+        // Simple crash in that case.
+        let g_cache = RACACHE.read().unwrap();
+        if g_cache.is_valid() {
+            return g_cache.ra_credential.clone();
+        }
+    }
+
+    // 2. Do the update
+
+    // Unwrapping failing means the RwLock is poisoned.
+    // Simple crash in that case.
+    let mut g_cache = RACACHE.write().unwrap();
+
+    // Here is the 100% serialized access to SVRCONFIG
+    // No other reader/writer exists in this branch
+    // Toc tou check
+    if g_cache.is_valid() {
+        return g_cache.ra_credential.clone();
+    }
+
+    // Do the renew
+    match RACache::new(g_cache.validity.as_secs()) {
+        // If RA renewal fails, we do not crash for the following reasons.
+        // 1. Crashing the enclave causes most data to be lost permanently,
+        //    since we do not have persistent key-value storage yet. On the
+        //    other hand, RA renewal failure may be temporary. We still have
+        //    a chance to recover from this failure in the future.
+        // 2. If renewal failed, the old certificate is used, the the client
+        //    can decide if they want to keep talking to the enclave.
+        // 3. The certificate has a 90 days valid duration. If RA keeps
+        //    failing for 90 days, the enclave itself will not serve any
+        //    client.
+        Err(e) => {
+            error!(
+                "RACredential renewal failed, use existing credential: {:?}",
+                e
+            );
+        }
+        Ok(new_cache) => *g_cache = new_cache,
+    };
+
+    g_cache.ra_credential.clone()
+}
+
+impl RACredential {
+    fn generate_and_endorse() -> Result<RACredential> {
+        let (prv_k, pub_k) = generate_sgx_ecc_keypair()?;
+        let report = create_attestation_report(&pub_k)?;
+        let payload = [report.report, report.signature, report.certificate].join("|");
+
+        let key_pair = Secp256k1KeyPair::new(prv_k, pub_k);
+        let cert_der =
+            key_pair.create_cert_with_extension("Teaclave", "Teaclave", &payload.as_bytes());
+        let prv_key_der = key_pair.private_key_into_der();
+        let sha256 = rsgx_sha256_slice(&prv_key_der)?;
+
+        Ok(RACredential {
+            cert: cert_der,
+            private_key: prv_key_der,
+            private_key_sha256: sha256,
+        })
+    }
+}
+
+impl RACache {
+    fn new(valid_secs: u64) -> Result<RACache> {
+        let ra_credential = RACredential::generate_and_endorse()?;
+        let gen_time = SystemTime::now();
+        let validity = time::Duration::from_secs(valid_secs);
+        Ok(RACache {
+            ra_credential,
+            gen_time,
+            validity,
+        })
+    }
+
+    fn is_valid(&self) -> bool {
+        let dur = SystemTime::now().duration_since(self.gen_time);
+        dur.is_ok() && dur.unwrap() < self.validity
+    }
+}
+
+fn generate_sgx_ecc_keypair() -> Result<(sgx_ec256_private_t, sgx_ec256_public_t)> {
+    let ecc_handle = SgxEccHandle::new();
+    ecc_handle.open()?;
+    let (prv_k, pub_k) = ecc_handle.create_key_pair()?;
+    ecc_handle.close()?;
+    Ok((prv_k, pub_k))
+}
+
+impl Secp256k1KeyPair {
+    fn new(prv_k: sgx_ec256_private_t, pub_k: sgx_ec256_public_t) -> Self {
+        Self { prv_k, pub_k }
+    }
+
+    pub fn private_key_into_der(&self) -> Vec<u8> {
+        use bit_vec::BitVec;
+        use yasna::construct_der;
+        use yasna::models::ObjectIdentifier;
+        use yasna::Tag;
+
+        let ec_public_key_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 2, 1]);
+        let prime256v1_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 3, 1, 7]);
+
+        let pub_key_bytes = self.public_key_into_bytes();
+        let prv_key_bytes = self.private_key_into_bytes();
+
+        // Construct private key in DER.
+        construct_der(|writer| {
+            writer.write_sequence(|writer| {
+                writer.next().write_u8(0);
+                writer.next().write_sequence(|writer| {
+                    writer.next().write_oid(&ec_public_key_oid);
+                    writer.next().write_oid(&prime256v1_oid);
+                });
+                let inner_key_der = construct_der(|writer| {
+                    writer.write_sequence(|writer| {
+                        writer.next().write_u8(1);
+                        writer.next().write_bytes(&prv_key_bytes);
+                        writer.next().write_tagged(Tag::context(1), |writer| {
+                            writer.write_bitvec(&BitVec::from_bytes(&pub_key_bytes));
+                        });
+                    });
+                });
+                writer.next().write_bytes(&inner_key_der);
+            });
+        })
+    }
+
+    pub fn create_cert_with_extension(
+        &self,
+        issuer: &str,
+        subject: &str,
+        payload: &[u8],
+    ) -> Vec<u8> {
+        use super::cert::*;
+        use bit_vec::BitVec;
+        use chrono::TimeZone;
+        use num_bigint::BigUint;
+        use std::time::UNIX_EPOCH;
+        use yasna::construct_der;
+        use yasna::models::ObjectIdentifier;
+        use yasna::models::UTCTime;
+
+        let ecdsa_with_sha256_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 4, 3, 2]);
+        let common_name_oid = ObjectIdentifier::from_slice(&[2, 5, 4, 3]);
+        let ec_public_key_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 2, 1]);
+        let prime256v1_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 3, 1, 7]);
+        let comment_oid = ObjectIdentifier::from_slice(&[2, 16, 840, 1, 113730, 1, 13]);
+
+        let pub_key_bytes = self.public_key_into_bytes();
+
+        // UNIX_EPOCH is the earliest time stamp. This unwrap should constantly succeed.
+        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
+        let issue_ts = chrono::Utc.timestamp(now.as_secs() as i64, 0);
+
+        // This is guaranteed to be a valid duration.
+        let expire = now + chrono::Duration::days(CERT_VALID_DAYS).to_std().unwrap();
+        let expire_ts = chrono::Utc.timestamp(expire.as_secs() as i64, 0);
+
+        // Construct certificate with payload in extension in DER.
+        let tbs_cert_der = construct_der(|writer| {
+            let version = 2i8;
+            let serial = 1u8;
+            let cert_sign_algo = asn1_seq!(ecdsa_with_sha256_oid.clone());
+            let issuer = asn1_seq!(asn1_seq!(asn1_seq!(
+                common_name_oid.clone(),
+                issuer.to_owned()
+            )));
+            let valid_range = asn1_seq!(
+                UTCTime::from_datetime(&issue_ts),
+                UTCTime::from_datetime(&expire_ts),
+            );
+            let subject = asn1_seq!(asn1_seq!(asn1_seq!(
+                common_name_oid.clone(),
+                subject.to_string(),
+            )));
+            let pub_key = asn1_seq!(
+                asn1_seq!(ec_public_key_oid, prime256v1_oid,),
+                BitVec::from_bytes(&pub_key_bytes),
+            );
+            let sgx_ra_cert_ext = asn1_seq!(asn1_seq!(comment_oid, payload.to_owned()));
+            let tbs_cert = asn1_seq!(
+                version,
+                serial,
+                cert_sign_algo,
+                issuer,
+                valid_range,
+                subject,
+                pub_key,
+                sgx_ra_cert_ext,
+            );
+            TbsCert::dump(writer, tbs_cert);
+        });
+
+        // There will be serious problems if this call fails. We might as well
+        // panic in this case, thus unwrap()
+        let ecc_handle = SgxEccHandle::new();
+        ecc_handle.open().unwrap();
+
+        let sig = ecc_handle
+            .ecdsa_sign_slice(&tbs_cert_der.as_slice(), &self.prv_k)
+            .unwrap();
+
+        let sig_der = yasna::construct_der(|writer| {
+            writer.write_sequence(|writer| {
+                let mut sig_x = sig.x;
+                sig_x.reverse();
+                let mut sig_y = sig.y;
+                sig_y.reverse();
+                writer.next().write_biguint(&BigUint::from_slice(&sig_x));
+                writer.next().write_biguint(&BigUint::from_slice(&sig_y));
+            });
+        });
+
+        yasna::construct_der(|writer| {
+            writer.write_sequence(|writer| {
+                writer.next().write_der(&tbs_cert_der.as_slice());
+                CertSignAlgo::dump(writer.next(), asn1_seq!(ecdsa_with_sha256_oid.clone()));
+                writer
+                    .next()
+                    .write_bitvec(&BitVec::from_bytes(&sig_der.as_slice()));
+            });
+        })
+    }
+
+    fn public_key_into_bytes(&self) -> Vec<u8> {
+        // The first byte must be 4, which indicates the uncompressed encoding.
+        let mut pub_key_bytes: Vec<u8> = vec![4];
+        pub_key_bytes.extend(self.pub_k.gx.iter().rev());
+        pub_key_bytes.extend(self.pub_k.gy.iter().rev());
+        pub_key_bytes
+    }
+
+    fn private_key_into_bytes(&self) -> Vec<u8> {
+        let mut prv_key_bytes: Vec<u8> = vec![];
+        prv_key_bytes.extend(self.prv_k.r.iter().rev());
+        prv_key_bytes
+    }
+}
+
 trait MayfailTraceForHttparseStatus<T> {
     fn to_mt_result(self: Self, file: &'static str, line: u32) -> Result<T>;
 }
@@ -506,223 +743,3 @@
 
     get_report_from_intel(ias_sock, &quote)
 }
-
-fn is_tls_config_updated(gen_time: &SystemTime) -> bool {
-    let dur = SystemTime::now().duration_since(*gen_time);
-    let max_allowed_diff = std::time::Duration::from_secs(86400u64);
-    dur.is_ok() && dur.unwrap() < max_allowed_diff
-}
-
-pub(crate) fn get_ra_cert() -> CertKeyPair {
-    // Check if the global cert valid
-    // If valid, use it directly
-    // If invalid, update it before use.
-    // Generate Keypair
-
-    // 1. Check if the global cert valid
-    //    Need block read here. It should wait for writers to complete
-    {
-        // Unwrapping failing means the RwLock is poisoned.
-        // Simple crash in that case.
-        let cache = RACACHE.read().unwrap();
-        if is_tls_config_updated(&cache.gen_time) {
-            return cache.cert_key.clone();
-        }
-    }
-
-    // 2. Do the update
-
-    // Unwrapping failing means the RwLock is poisoned.
-    // Simple crash in that case.
-    let mut cache = RACACHE.write().unwrap();
-
-    // Here is the 100% serialized access to SVRCONFIG
-    // No other reader/writer exists in this branch
-    // Toc tou check
-    if is_tls_config_updated(&cache.gen_time) {
-        return cache.cert_key.clone();
-    }
-
-    // Do the renew
-    *cache = match renew_ra_cert() {
-        // If RA renewal fails, we do not crash for the following reasons.
-        // 1. Crashing the enclave causes most data to be lost permanently,
-        //    since we do not have persistent key-value storage yet. On the
-        //    other hand, RA renewal failure may be temporary. We still have
-        //    a chance to recover from this failure in the future.
-        // 2. If renewal failed, the old certificate is used, the the client
-        //    can decide if they want to keep talking to the enclave.
-        // 3. The certificate has a 90 days valid duration. If RA keeps
-        //    failing for 90 days, the enclave itself will not serve any
-        //    client.
-        Err(e) => {
-            error!("RACACHE renewal failed: {:?}", e);
-            panic!()
-        }
-        Ok(new_cache) => new_cache,
-    };
-
-    cache.cert_key.clone()
-}
-
-fn renew_ra_cert() -> Result<RACache> {
-    let cert_key = CertKeyPair::new()?;
-    let gen_time = SystemTime::now();
-    Ok(RACache { cert_key, gen_time })
-}
-
-struct Secp256k1KeyPair {
-    prv_k: sgx_ec256_private_t,
-    pub_k: sgx_ec256_public_t,
-}
-
-impl Secp256k1KeyPair {
-    fn new(prv_k: sgx_ec256_private_t, pub_k: sgx_ec256_public_t) -> Self {
-        Self { prv_k, pub_k }
-    }
-
-    pub fn private_key_into_der(&self) -> Vec<u8> {
-        use bit_vec::BitVec;
-        use yasna::construct_der;
-        use yasna::models::ObjectIdentifier;
-        use yasna::Tag;
-
-        let ec_public_key_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 2, 1]);
-        let prime256v1_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 3, 1, 7]);
-
-        let pub_key_bytes = self.public_key_into_bytes();
-        let prv_key_bytes = self.private_key_into_bytes();
-
-        // Construct private key in DER.
-        construct_der(|writer| {
-            writer.write_sequence(|writer| {
-                writer.next().write_u8(0);
-                writer.next().write_sequence(|writer| {
-                    writer.next().write_oid(&ec_public_key_oid);
-                    writer.next().write_oid(&prime256v1_oid);
-                });
-                let inner_key_der = construct_der(|writer| {
-                    writer.write_sequence(|writer| {
-                        writer.next().write_u8(1);
-                        writer.next().write_bytes(&prv_key_bytes);
-                        writer.next().write_tagged(Tag::context(1), |writer| {
-                            writer.write_bitvec(&BitVec::from_bytes(&pub_key_bytes));
-                        });
-                    });
-                });
-                writer.next().write_bytes(&inner_key_der);
-            });
-        })
-    }
-
-    pub fn create_cert_with_extension(
-        &self,
-        issuer: &str,
-        subject: &str,
-        payload: &[u8],
-    ) -> Vec<u8> {
-        use super::cert::*;
-        use bit_vec::BitVec;
-        use chrono::TimeZone;
-        use num_bigint::BigUint;
-        use std::time::UNIX_EPOCH;
-        use yasna::construct_der;
-        use yasna::models::ObjectIdentifier;
-        use yasna::models::UTCTime;
-
-        let ecdsa_with_sha256_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 4, 3, 2]);
-        let common_name_oid = ObjectIdentifier::from_slice(&[2, 5, 4, 3]);
-        let ec_public_key_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 2, 1]);
-        let prime256v1_oid = ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 3, 1, 7]);
-        let comment_oid = ObjectIdentifier::from_slice(&[2, 16, 840, 1, 113730, 1, 13]);
-
-        let pub_key_bytes = self.public_key_into_bytes();
-
-        // UNIX_EPOCH is the earliest time stamp. This unwrap should constantly succeed.
-        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
-        let issue_ts = chrono::Utc.timestamp(now.as_secs() as i64, 0);
-
-        // This is guaranteed to be a valid duration.
-        let expire = now + chrono::Duration::days(CERT_VALID_DAYS).to_std().unwrap();
-        let expire_ts = chrono::Utc.timestamp(expire.as_secs() as i64, 0);
-
-        // Construct certificate with payload in extension in DER.
-        let tbs_cert_der = construct_der(|writer| {
-            let version = 2i8;
-            let serial = 1u8;
-            let cert_sign_algo = asn1_seq!(ecdsa_with_sha256_oid.clone());
-            let issuer = asn1_seq!(asn1_seq!(asn1_seq!(
-                common_name_oid.clone(),
-                issuer.to_owned()
-            )));
-            let valid_range = asn1_seq!(
-                UTCTime::from_datetime(&issue_ts),
-                UTCTime::from_datetime(&expire_ts),
-            );
-            let subject = asn1_seq!(asn1_seq!(asn1_seq!(
-                common_name_oid.clone(),
-                subject.to_string(),
-            )));
-            let pub_key = asn1_seq!(
-                asn1_seq!(ec_public_key_oid, prime256v1_oid,),
-                BitVec::from_bytes(&pub_key_bytes),
-            );
-            let sgx_ra_cert_ext = asn1_seq!(asn1_seq!(comment_oid, payload.to_owned()));
-            let tbs_cert = asn1_seq!(
-                version,
-                serial,
-                cert_sign_algo,
-                issuer,
-                valid_range,
-                subject,
-                pub_key,
-                sgx_ra_cert_ext,
-            );
-            TbsCert::dump(writer, tbs_cert);
-        });
-
-        // There will be serious problems if this call fails. We might as well
-        // panic in this case, thus unwrap()
-        let ecc_handle = SgxEccHandle::new();
-        ecc_handle.open().unwrap();
-
-        let sig = ecc_handle
-            .ecdsa_sign_slice(&tbs_cert_der.as_slice(), &self.prv_k)
-            .unwrap();
-
-        let sig_der = yasna::construct_der(|writer| {
-            writer.write_sequence(|writer| {
-                let mut sig_x = sig.x;
-                sig_x.reverse();
-                let mut sig_y = sig.y;
-                sig_y.reverse();
-                writer.next().write_biguint(&BigUint::from_slice(&sig_x));
-                writer.next().write_biguint(&BigUint::from_slice(&sig_y));
-            });
-        });
-
-        yasna::construct_der(|writer| {
-            writer.write_sequence(|writer| {
-                writer.next().write_der(&tbs_cert_der.as_slice());
-                CertSignAlgo::dump(writer.next(), asn1_seq!(ecdsa_with_sha256_oid.clone()));
-                writer
-                    .next()
-                    .write_bitvec(&BitVec::from_bytes(&sig_der.as_slice()));
-            });
-        })
-    }
-
-    fn public_key_into_bytes(&self) -> Vec<u8> {
-        // The first byte must be 4, which indicates the uncompressed encoding.
-        let mut pub_key_bytes: Vec<u8> = vec![4];
-        pub_key_bytes.extend(self.pub_k.gx.iter().rev());
-        pub_key_bytes.extend(self.pub_k.gy.iter().rev());
-        pub_key_bytes
-    }
-
-    fn private_key_into_bytes(&self) -> Vec<u8> {
-        let mut prv_key_bytes: Vec<u8> = vec![];
-        prv_key_bytes.extend(self.prv_k.r.iter().rev());
-        prv_key_bytes
-    }
-}
diff --git a/mesatee_core/src/rpc/sgx/server.rs b/mesatee_core/src/rpc/sgx/server.rs
index be6c281..c687fc3 100644
--- a/mesatee_core/src/rpc/sgx/server.rs
+++ b/mesatee_core/src/rpc/sgx/server.rs
@@ -17,7 +17,6 @@
 
 use std::collections::HashMap;
 use std::sync::Arc;
-use std::vec::Vec;
 
 use crate::rpc::sgx::EnclaveAttr;
 use crate::Error;
@@ -43,18 +42,15 @@
 pub(crate) fn get_tls_config(
     client_attr: Option<EnclaveAttr>,
 ) -> Result<Arc<rustls::ServerConfig>> {
-    use crate::rpc::sgx::ra::get_ra_cert;
+    use crate::rpc::sgx::ra::get_current_ra_credential;
 
-    // To re-use existing TLS cache, we need to first check if the server has
-    // updated his RA cert
-    let cert_key = get_ra_cert();
+    let ra_credential = get_current_ra_credential();
 
     let client_attr = match client_attr {
         Some(attr) => Arc::new(attr),
         None => {
-            let mut certs = Vec::new();
-            certs.push(rustls::Certificate(cert_key.cert));
-            let privkey = rustls::PrivateKey(cert_key.private_key);
+            let certs = vec![rustls::Certificate(ra_credential.cert)];
+            let privkey = rustls::PrivateKey(ra_credential.private_key);
             // Build a default authenticator which allow every authenticated client
             let authenticator = rustls::NoClientAuth::new();
             let mut cfg = rustls::ServerConfig::new(authenticator);
@@ -71,8 +67,8 @@
         }
     }
 
-    let certs = vec![rustls::Certificate(cert_key.cert)];
-    let privkey = rustls::PrivateKey(cert_key.private_key);
+    let certs = vec![rustls::Certificate(ra_credential.cert)];
+    let privkey = rustls::PrivateKey(ra_credential.private_key);
 
     let mut server_cfg = rustls::ServerConfig::new(client_attr.clone());
     server_cfg
@@ -82,9 +78,9 @@
     let final_arc = Arc::new(server_cfg);
 
     if let Ok(mut cfg_cache) = SERVER_CONFIG_CACHE.try_write() {
-        if cfg_cache.private_key_sha256 != cert_key.private_key_sha256 {
+        if cfg_cache.private_key_sha256 != ra_credential.private_key_sha256 {
             *cfg_cache = ServerConfigCache {
-                private_key_sha256: cert_key.private_key_sha256,
+                private_key_sha256: ra_credential.private_key_sha256,
                 target_configs: HashMap::new(),
             }
         }