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 2020/06/11 23:21:11 UTC
[incubator-teaclave] branch master updated: Add an example of RSA
signature (#348)
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 3bccc70 Add an example of RSA signature (#348)
3bccc70 is described below
commit 3bccc709125ae776c7795650db86774be300f6ef
Author: renxingliang <53...@users.noreply.github.com>
AuthorDate: Thu Jun 11 19:21:02 2020 -0400
Add an example of RSA signature (#348)
---
cmake/scripts/test.sh | 1 +
examples/python/builtin_rsa_sign.py | 115 +++++++++++++++++++++
executor/Cargo.toml | 2 +
executor/src/builtin.rs | 4 +-
function/README.md | 1 +
function/src/lib.rs | 3 +
function/src/rsa_sign.rs | 114 ++++++++++++++++++++
services/proto/src/teaclave_frontend_service.rs | 1 -
.../functions/rsa_sign/expected_rsasign.txt | 1 +
tests/fixtures/functions/rsa_sign/key.der | Bin 0 -> 1191 bytes
tests/fixtures/functions/rsa_sign/rsakey.enc | Bin 0 -> 4096 bytes
11 files changed, 240 insertions(+), 2 deletions(-)
diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index 87e48a8..f437d02 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -163,6 +163,7 @@ run_examples() {
python3 builtin_gbdt_train.py
python3 builtin_online_decrypt.py
python3 builtin_private_join_and_compute.py
+ python3 builtin_rsa_sign.py
popd
# kill all background services
diff --git a/examples/python/builtin_rsa_sign.py b/examples/python/builtin_rsa_sign.py
new file mode 100644
index 0000000..7130262
--- /dev/null
+++ b/examples/python/builtin_rsa_sign.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+import sys
+
+from teaclave import (AuthenticationService, FrontendService,
+ AuthenticationClient, FrontendClient, FunctionInput,
+ FunctionOutput, OwnerList, DataMap)
+from utils import (AUTHENTICATION_SERVICE_ADDRESS, FRONTEND_SERVICE_ADDRESS,
+ AS_ROOT_CA_CERT_PATH, ENCLAVE_INFO_PATH, USER_ID,
+ USER_PASSWORD)
+
+
+def get_client(user_id, user_password):
+ auth_client = AuthenticationService(
+ AUTHENTICATION_SERVICE_ADDRESS, AS_ROOT_CA_CERT_PATH,
+ ENCLAVE_INFO_PATH).connect().get_client()
+
+ print("[+] registering user")
+ auth_client.user_register(user_id, user_password)
+
+ print("[+] login")
+ token = auth_client.user_login(user_id, user_password)
+
+ client = FrontendService(FRONTEND_SERVICE_ADDRESS, AS_ROOT_CA_CERT_PATH,
+ ENCLAVE_INFO_PATH).connect().get_client()
+ metadata = {"id": user_id, "token": token}
+ client.metadata = metadata
+ return client
+
+
+def register_input_file(client):
+ """
+ Commands when encrypting input files:
+ ./teaclave_cli encrypt
+ --algorithm teaclave-file-128
+ --input-file ./tests/fixtures/functions/rsa_sign/key.der
+ --key 00000000000000000000000000000003
+ --output-file ./tests/fixtures/functions/rsa_sign/rsakey.enc
+ --cmac-flag
+ """
+ url = "http://localhost:6789/fixtures/functions/rsa_sign/rsakey.enc"
+ cmac = "4de3bb77327c82923640835c6e5ada66"
+ schema = "teaclave-file-128"
+ key = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]
+ iv = []
+ key_data_id = client.register_input_file(url, schema, key, iv, cmac)
+
+ return key_data_id
+
+
+def register_func(client):
+ function_id = client.register_function(
+ name="builtin-rsa-sign",
+ description="Native Rsa Signing Function",
+ executor_type="builtin",
+ arguments=["data"],
+ inputs=[FunctionInput("rsa_key", "Input key file.")])
+
+ return function_id
+
+
+def create_task(client, function_id, input_file_user):
+ task_id = client.create_task(
+ function_id=function_id,
+ executor="builtin",
+ function_arguments=({
+ "data": "test data",
+ }),
+ inputs_ownership=[OwnerList("rsa_key", [input_file_user])])
+
+ return task_id
+
+
+def rsa_task():
+ client1 = get_client("rsa_sign_user1", "password1")
+ client2 = get_client("rsa_sign_user2", "password2")
+
+ print("[+] registering key file")
+ key_id = register_input_file(client1)
+ print("[+] key file id" + key_id)
+
+ print("[+] registering function")
+ function_id = register_func(client2)
+ print("[+] function id" + function_id)
+
+ print("[+] creating task")
+ task_id = create_task(client2, function_id, "rsa_sign_user1")
+ print("[+] task id" + task_id)
+
+ print("[+] assigning data to task")
+ client1.assign_data_to_task(task_id, [DataMap("rsa_key", key_id)], [])
+
+ print("[+] user1 approving task")
+ client1.approve_task(task_id)
+
+ print("[+] user2 approving task")
+ client2.approve_task(task_id)
+
+ print("[+] invoking task")
+ client2.invoke_task(task_id)
+
+ print("[+] getting result")
+ result = client2.get_task_result(task_id)
+ print("[+] done")
+
+ return bytes(result)
+
+
+def main():
+ rt = rsa_task()
+ print("[+] function return: ", rt)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/executor/Cargo.toml b/executor/Cargo.toml
index 3755037..c102d44 100644
--- a/executor/Cargo.toml
+++ b/executor/Cargo.toml
@@ -33,6 +33,7 @@ full_builtin_function = [
"builtin_logistic_regression_train",
"builtin_online_decrypt",
"builtin_private_join_and_compute",
+ "builtin_rsa_sign",
]
builtin_echo = []
@@ -42,6 +43,7 @@ builtin_logistic_regression_predict = []
builtin_logistic_regression_train = []
builtin_online_decrypt = []
builtin_private_join_and_compute = []
+builtin_rsa_sign = []
[dependencies]
log = { version = "0.4.6", features = ["release_max_level_info"] }
diff --git a/executor/src/builtin.rs b/executor/src/builtin.rs
index ef4c413..5874d74 100644
--- a/executor/src/builtin.rs
+++ b/executor/src/builtin.rs
@@ -20,7 +20,7 @@ use std::prelude::v1::*;
use teaclave_function::{
Echo, GbdtPredict, GbdtTrain, LogisticRegressionPredict, LogisticRegressionTrain,
- OnlineDecrypt, PrivateJoinAndCompute,
+ OnlineDecrypt, PrivateJoinAndCompute, RsaSign,
};
use teaclave_types::{FunctionArguments, FunctionRuntime, TeaclaveExecutor};
@@ -54,6 +54,8 @@ impl TeaclaveExecutor for BuiltinFunctionExecutor {
OnlineDecrypt::NAME => OnlineDecrypt::new().run(arguments, runtime),
#[cfg(feature = "builtin_private_join_and_compute")]
PrivateJoinAndCompute::NAME => PrivateJoinAndCompute::new().run(arguments, runtime),
+ #[cfg(feature = "builtin_rsa_sign")]
+ RsaSign::NAME => RsaSign::new().run(arguments, runtime),
_ => bail!("Function not found."),
}
}
diff --git a/function/README.md b/function/README.md
index 42df464..91bed63 100644
--- a/function/README.md
+++ b/function/README.md
@@ -20,6 +20,7 @@ Currently, we have these built-in functions:
- `builtin-logistic-regression-predict`: LR prediction with input model and input test data.
- `builtin-private-join-and-compute`: Find intersection of muti-parties' input
data and compute sum of the common items.
+ - `builtin-rsa-sign`: Signing data with RSA key.
The function arguments are in JSON format and can be serialized to a Rust struct
very easily. You can learn more about supported arguments in the implementation
diff --git a/function/src/lib.rs b/function/src/lib.rs
index 0e83885..2d43640 100644
--- a/function/src/lib.rs
+++ b/function/src/lib.rs
@@ -29,6 +29,7 @@ mod logistic_regression_predict;
mod logistic_regression_train;
mod online_decrypt;
mod private_join_and_compute;
+mod rsa_sign;
pub use echo::Echo;
pub use gbdt_predict::GbdtPredict;
@@ -37,6 +38,7 @@ pub use logistic_regression_predict::LogisticRegressionPredict;
pub use logistic_regression_train::LogisticRegressionTrain;
pub use online_decrypt::OnlineDecrypt;
pub use private_join_and_compute::PrivateJoinAndCompute;
+pub use rsa_sign::RsaSign;
#[cfg(feature = "enclave_unit_test")]
pub mod tests {
@@ -52,6 +54,7 @@ pub mod tests {
logistic_regression_predict::tests::run_tests(),
online_decrypt::tests::run_tests(),
private_join_and_compute::tests::run_tests(),
+ rsa_sign::tests::run_tests(),
)
}
}
diff --git a/function/src/rsa_sign.rs b/function/src/rsa_sign.rs
new file mode 100644
index 0000000..48188fc
--- /dev/null
+++ b/function/src/rsa_sign.rs
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#[cfg(feature = "mesalock_sgx")]
+use std::prelude::v1::*;
+use std::vec;
+
+use ring::{rand, signature};
+
+use std::convert::TryFrom;
+use teaclave_types::{FunctionArguments, FunctionRuntime};
+
+const IN_DATA: &str = "rsa_key";
+
+#[derive(serde::Deserialize)]
+struct RsaSignArguments {
+ data: String,
+}
+
+impl TryFrom<FunctionArguments> for RsaSignArguments {
+ type Error = anyhow::Error;
+
+ fn try_from(arguments: FunctionArguments) -> Result<Self, Self::Error> {
+ use anyhow::Context;
+ serde_json::from_str(&arguments.into_string()).context("Cannot deserialize arguments")
+ }
+}
+
+#[derive(Default)]
+pub struct RsaSign;
+
+impl RsaSign {
+ pub const NAME: &'static str = "builtin-rsa-sign";
+
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ pub fn run(
+ &self,
+ arguments: FunctionArguments,
+ runtime: FunctionRuntime,
+ ) -> anyhow::Result<String> {
+ let args = RsaSignArguments::try_from(arguments)?;
+
+ let mut key = Vec::new();
+ let mut f = runtime.open_input(IN_DATA)?;
+ f.read_to_end(&mut key)?;
+ let key_pair = signature::RsaKeyPair::from_der(&key)?;
+ let mut sig = vec![0; key_pair.public_modulus_len()];
+ let rng = rand::SystemRandom::new();
+ key_pair.sign(
+ &signature::RSA_PKCS1_SHA256,
+ &rng,
+ args.data.as_bytes(),
+ &mut sig,
+ )?;
+
+ let output_base64 = base64::encode(&sig);
+ Ok(output_base64)
+ }
+}
+
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+ use super::*;
+ use serde_json::json;
+ use std::untrusted::fs;
+ use teaclave_crypto::*;
+ use teaclave_runtime::*;
+ use teaclave_test_utils::*;
+ use teaclave_types::*;
+
+ pub fn run_tests() -> bool {
+ run_tests!(test_rsa_sign)
+ }
+
+ fn test_rsa_sign() {
+ let arguments = FunctionArguments::from_json(json!({
+ "data": "test data",
+ }))
+ .unwrap();
+
+ let plain_input = "fixtures/functions/rsa_sign/key.der";
+ let expected_output = "fixtures/functions/rsa_sign/expected_rsasign.txt";
+
+ let input_files = StagedFiles::new(hashmap!(
+ IN_DATA =>
+ StagedFileInfo::new(plain_input, TeaclaveFile128Key::random(), FileAuthTag::mock())
+ ));
+
+ let output_files = StagedFiles::default();
+ let runtime = Box::new(RawIoRuntime::new(input_files, output_files));
+
+ let summary = RsaSign::new().run(arguments, runtime).unwrap();
+ let mut expected_string = fs::read_to_string(&expected_output).unwrap();
+ expected_string = expected_string.replace("\n", "");
+ assert_eq!(summary, expected_string);
+ }
+}
diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs
index abc30e5..e784f59 100644
--- a/services/proto/src/teaclave_frontend_service.rs
+++ b/services/proto/src/teaclave_frontend_service.rs
@@ -553,7 +553,6 @@ impl std::convert::TryFrom<proto::RegisterInputFileRequest> for RegisterInputFil
.crypto_info
.ok_or_else(|| anyhow!("missing crypto_info"))?
.try_into()?;
-
Ok(RegisterInputFileRequest {
url,
cmac,
diff --git a/tests/fixtures/functions/rsa_sign/expected_rsasign.txt b/tests/fixtures/functions/rsa_sign/expected_rsasign.txt
new file mode 100644
index 0000000..28599f2
--- /dev/null
+++ b/tests/fixtures/functions/rsa_sign/expected_rsasign.txt
@@ -0,0 +1 @@
+tmgoOYVBmGOQNvb1Rrf13L0bchIlbRx2rFf14udRmZrXzaGrIH3z26tSjD6a3RvKGh/vgW8bjbr7caSdjUxNPI/LJEk/TXX0ilkhfV957fBgtOtB2YFqbKGFR6zoHHC2zgOWDUXidGJqMQFD/SY5tBe0t4bFhHPkxnU/lTTwK+sg8ECNCXTvblUsI7dMVzMHV3q29NwE43DvrM+9pbt9QGm8sGatAnpcK/RVp1nk60FQJvwe0zUQXvpPMpCv8vO+/kKEZkwXw8WwPOvCNI5jE/8gGnQHCH/3UgvZjfgp978htHOky7BNskYIHsc87dClIjMhjfMto5pm14SdCpmmHw==
diff --git a/tests/fixtures/functions/rsa_sign/key.der b/tests/fixtures/functions/rsa_sign/key.der
new file mode 100644
index 0000000..3857aa4
Binary files /dev/null and b/tests/fixtures/functions/rsa_sign/key.der differ
diff --git a/tests/fixtures/functions/rsa_sign/rsakey.enc b/tests/fixtures/functions/rsa_sign/rsakey.enc
new file mode 100644
index 0000000..1989b38
Binary files /dev/null and b/tests/fixtures/functions/rsa_sign/rsakey.enc differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org