You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2019/12/25 01:29:43 UTC

[incubator-teaclave] branch master updated: [core] Refactor ECC key conversion and cert generation functions (#192)

This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git


The following commit(s) were added to refs/heads/master by this push:
     new b1f99f3  [core] Refactor ECC key conversion and cert generation functions (#192)
b1f99f3 is described below

commit b1f99f308ca2b420de0564ae830cf1a484b5098f
Author: Mingshen Sun <bo...@mssun.me>
AuthorDate: Tue Dec 24 17:29:38 2019 -0800

    [core] Refactor ECC key conversion and cert generation functions (#192)
---
 mesatee_core/src/rpc/sgx/ra.rs | 283 +++++++++++++++++++++--------------------
 1 file changed, 144 insertions(+), 139 deletions(-)

diff --git a/mesatee_core/src/rpc/sgx/ra.rs b/mesatee_core/src/rpc/sgx/ra.rs
index bbe20a1..c0b7f84 100644
--- a/mesatee_core/src/rpc/sgx/ra.rs
+++ b/mesatee_core/src/rpc/sgx/ra.rs
@@ -40,7 +40,7 @@ use std::io::{Read, Write};
 use std::net::TcpStream;
 use std::ptr;
 use std::sync::{Arc, SgxRwLock};
-use std::time::{SystemTime, UNIX_EPOCH};
+use std::time::SystemTime;
 use std::untrusted::time::SystemTimeEx;
 
 use lazy_static::lazy_static;
@@ -106,8 +106,9 @@ impl CertKeyPair {
             } =<< create_attestation_report(&pub_k);
             let payload = [attn_report, sig, cert].join("|");
 
-            let cert_der = gen_ecc_cert(payload, &prv_k, &pub_k);
-            let prv_key_der = convert_ec_private_to_der(&prv_k, &pub_k);
+            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,
@@ -570,154 +571,158 @@ fn renew_ra_cert() -> Result<RACache> {
     Ok(RACache { cert_key, gen_time })
 }
 
-fn make_ecc_public_key_bytes(pub_k: &sgx_ec256_public_t) -> Vec<u8> {
-    // Generate public key bytes
-    // The first must be 4, encoding for "uncompressed".
-    // Ref: https://github.com/briansmith/ring/blob/772fc080898c7b330fff99701c2a534580ebbf8c/src/ec/suite_b/public_key.rs#L30
-    let mut pub_key_bytes: Vec<u8> = vec![4];
-    pub_key_bytes.extend(pub_k.gx.iter().rev());
-    pub_key_bytes.extend(pub_k.gy.iter().rev());
-    pub_key_bytes
+struct Secp256k1KeyPair {
+    prv_k: sgx_ec256_private_t,
+    pub_k: sgx_ec256_public_t,
 }
 
-fn gen_ecc_cert(
-    payload: String,
-    prv_k: &sgx_ec256_private_t,
-    pub_k: &sgx_ec256_public_t,
-) -> Vec<u8> {
-    const ISSUER: &str = "MesaTEE";
-    const SUBJECT: &str = "MesaTEE";
-
-    use super::cert::*;
-
-    let pub_key_bytes = make_ecc_public_key_bytes(pub_k);
-
-    // Generate Certificate DER
-    let tbs_cert_der = yasna::construct_der(|writer| {
-        let version = 2i8;
-        let serial = 1u8;
-        let cert_sign_algo = asn1_seq!(yasna::models::ObjectIdentifier::from_slice(&[
-            1, 2, 840, 10045, 4, 3, 2,
-        ]),);
-        let issuer = asn1_seq!(asn1_seq!(asn1_seq!(
-            yasna::models::ObjectIdentifier::from_slice(&[2, 5, 4, 3]),
-            ISSUER.to_string(),
-        ),),);
+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 guarenteed to be a valid duration..
+
+        // 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);
-        let valid_range = asn1_seq!(
-            yasna::models::UTCTime::from_datetime(&issue_ts),
-            yasna::models::UTCTime::from_datetime(&expire_ts),
-        );
-        let subject = asn1_seq!(asn1_seq!(asn1_seq!(
-            yasna::models::ObjectIdentifier::from_slice(&[2, 5, 4, 3]),
-            SUBJECT.to_string(),
-        ),),);
-        let pub_key = asn1_seq!(
-            asn1_seq!(
-                yasna::models::ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 2, 1,]),
-                yasna::models::ObjectIdentifier::from_slice(&[1, 2, 840, 10045, 3, 1, 7,]),
-            ),
-            bit_vec::BitVec::from_bytes(&pub_key_bytes),
-        );
-        let sgx_ra_cert_ext = asn1_seq!(asn1_seq!(
-            yasna::models::ObjectIdentifier::from_slice(&[2, 16, 840, 1, 113730, 1, 13,]),
-            payload.into_bytes(),
-        ),);
-        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);
-    });
-
-    let cert_sign_algo = asn1_seq!(yasna::models::ObjectIdentifier::from_slice(&[
-        1, 2, 840, 10045, 4, 3, 2,
-    ]),);
-
-    // 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(), &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(&num_bigint::BigUint::from_slice(&sig_x));
-            writer
-                .next()
-                .write_biguint(&num_bigint::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(), cert_sign_algo);
-            writer
-                .next()
-                .write_bitvec(&bit_vec::BitVec::from_bytes(&sig_der.as_slice()));
-        });
-    })
-}
 
-fn convert_ec_private_to_der(prv_k: &sgx_ec256_private_t, pub_k: &sgx_ec256_public_t) -> Vec<u8> {
-    // Generate public key bytes
-    let pub_key_bytes = make_ecc_public_key_bytes(pub_k);
+        // 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);
+        });
 
-    // Generate private key bytes
-    let mut prv_key_bytes: Vec<u8> = vec![];
-    prv_key_bytes.extend(prv_k.r.iter().rev());
+        // 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));
+            });
+        });
 
-    // Generate Private Key DER
-    yasna::construct_der(|writer| {
-        writer.write_sequence(|writer| {
-            writer.next().write_u8(0);
-            writer.next().write_sequence(|writer| {
-                writer
-                    .next()
-                    .write_oid(&yasna::models::ObjectIdentifier::from_slice(&[
-                        1, 2, 840, 10045, 2, 1,
-                    ]));
+        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_oid(&yasna::models::ObjectIdentifier::from_slice(&[
-                        1, 2, 840, 10045, 3, 1, 7,
-                    ]));
-            });
-            let inner_key_der = yasna::construct_der(|writer| {
-                writer.write_sequence(|writer| {
-                    writer.next().write_u8(1);
-                    writer.next().write_bytes(&prv_key_bytes);
-                    writer
-                        .next()
-                        .write_tagged(yasna::Tag::context(1), |writer| {
-                            writer.write_bitvec(&bit_vec::BitVec::from_bytes(&pub_key_bytes));
-                        });
-                });
+                    .write_bitvec(&BitVec::from_bytes(&sig_der.as_slice()));
             });
-            writer.next().write_bytes(&inner_key_der);
-        });
-    })
+        })
+    }
+
+    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
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org