This library is a thin Rust shim that wraps the IronOxide Rust SDK and uses the Rust Swig toolset to generate bindings. It currently contains SDKs for C++, Java, and Android.
Copyright (c) 2021 IronCore Labs, Inc. All rights reserved.
IronCore Labs SDK bindings which are generated using swig
License: GNU Affero General Public License v3.0
This library is a thin Rust shim that wraps the IronOxide Rust SDK and uses the Rust Swig toolset to generate bindings. It currently contains SDKs for C++, Java, and Android.
Copyright (c) 2021 IronCore Labs, Inc. All rights reserved.
As an android developer
I want an easy to bring ironoxide-android into my app
AC:
DeviceCreateOpts
, UserCreateOpts
, and GroupCreateOpts
all currently have an empty constructor to use default values, and a .create()
function to specify options. These .create()
s can become constructors as well to make them more obvious.
First discussed here
As an ironoxide-java maintainer, I want a consistent and easy release process.
AC:
RELEASING.md
is in this repository that explains how to make a release. (How to pick version number, coordinate versions between Cargo and sbt, etc.)As a starting point, take a look at the cpp-swig-test branch of ironoxide-java. In particular, you will need the build.rs
from there. If you want to test that it works or need a starting point for building C++ unit tests, then cd cpp
and run cmake
then make
. That will produce a binary that you can run that will fail since it has a hard coded JWT, but should provide a starting point for writing similar code for testing purposes.
The current directories that things get dumped in aren't ideal. See #93 for some thoughts about how that can be adjusted.
ironcore-id
that's on my local network.Can we configure the endpoint that we talk to via a Java system property or an environment variable?
The docs can't be generated right now, so sbt release cannot be run.
There are 2 things wrong:
So this:
/// @param a0 `jwt` - valid IronCore JWT
/// @param a1 `password` - password used to encrypt and escrow the user's private key
/// @param a2 `deviceCreateOptions` - optional values, like device name
///
/// @return details about the newly created device
static_method generate_new_device(_:&str, _:&str, _: &DeviceCreateOpts) -> Result<DeviceContext, String>; alias generateNewDevice;
should become
/// Generates a new device for the user specified in the signed JWT.
///
/// This will result in a new transform key (from the user's master private key to the new device's public key)
/// being generated and stored with the IronCore Service.
///
/// @param jwt - valid IronCore JWT
/// @param password - password used to encrypt and escrow the user's private key
/// @param deviceCreateOptions - optional values, like device name
///
/// @return details about the newly created device
static_method generate_new_device(jwt:&str, password:&str, deviceCreateOptions: &DeviceCreateOpts) -> Result<DeviceContext, String>; alias generateNewDevice;
Also, all of our @throws
error because you're apparently not suppose to put the cause of the throw on that line. We should figure out a better way to convey that info.
To test this you should run cargo b
and then run sbt doc
.
As and ironoxide-java user
I want to utilize the new feature flag sync API
since the sync API is behind a feature flag now
AC:
Ironoxide issue #25 will change the serialization of DeviceContext
and include a device_id
in its creation.
Ironoxide-java will need to pass a device_id
for its creation of DeviceContexts
Move android-by-hand into the multiworkspace structure. We should also add all supported android architectures to CI.
The main new feature is that ironoxide 0.9.0 is able to be shared across threads.
As a group admin
I want to be able to rotate my private key (without changing my public key)
so that I can be sure that anyone who had access to the old private key can't administer the group after rotation.
An initial Swift library should be a wrapper that calls through to Rust via the C bindings. Initial goal should be to just setup a swift project and get a basic init/encrypt/decrypt roundtrip to work. Here are some links that will be useful in the process of wrapping C:
Most of these are easy to find, but I kept losing track of that first bullet item, so hopefully this makes life a bit easier.
Until CentOS8 is released, we'll have to these builds in a CentOS7 container with some extra magic.
Do builds in a CentOS8 container so we get the right version of OpenSSL linked in to the native library.
As an ironoxide-java user
I want the released binaries for ironoxide-java to be signed
so that I can know they haven't been corrupted or tampered with
AC:
RELEASING.md
fileAs a user
I want to be able to rotate my private key (without changing my public key)
so that I can be sure that anyone who had access to my private key previously, can't decrypt data
See IronCoreLabs/ironoxide#44 for ironoxide implementation details
As a dev using ironoxide-java
I want a binary available for my OS
so that I don't have to install a rust toolchain to use ironoxide-java
in my application
AC
Possibly helpful:
https://rust-lang-nursery.github.io/cli-wg/tutorial/packaging.html
See IronCoreLabs/ironoxide#21 -- Similar function sig.
IronCoreLabs/ironoxide#15 Java binding to support calling this.
As an application developer using ironoxide-java
I want to run my application on a Redhat Atomic based docker image
Points of concern:
Related: Can we use a pure Rust TLS impl?
AC:
Rename to PolicyQuery for consistency with server, other APIs
We would like to upgrade to the rust_swig
dependency to avoid falling too far behind current development.
We have a history of depending on a certain commit in master as the project is under active development, but depending on 0.4 is also an option.
As an ironoxide-android developer
I want a clear way to build and release the AAR
Probably not for now: Possibly consider packaging shared libs into jars like https://github.com/xerial/sqlite-jdbc
AC
release
workflow builds an AAR containing native libs for various Android architecturesAs devops, building/deploying services integrated with ironoxide-java
I want to know if the service has properly linked ironoxide-java as early as possible
Some ideas were:
The rust code allows sharing a document with a list of users or groups on create. This code didn't make it to the JNI layer.
Rust swig allows us to write Rust-based comments in our .rs.in
file and have those comments be propagated out to the generated Java class files. We'll need this in order to get any decent javadoc generation for when we publish the JAR.
Consume exposed option in IronCoreLabs/ironoxide#2
We have a rule in ironoxide-java that all our functions take borrows and return owned data. We thought that rust_swig was doing something with Options to clone the data for us (like how we don't need borrows in Vecs), but that's not true. If you make a GroupName
and use it to create multiple GroupCreateOpts
, only the first group will get the desired name. Instead of giving an error, using it a second time is interpreted as passing null, so the group would have no name.
We need to do a pass on all of our functions and make sure that they only take borrows (or Options of borrow). The data should then be copied/cloned.
There are probably some other cleanups and improvements we could do at the same time (like using cargo clippy
suggestions)
Add ability to clear the policy cache once IronCoreLabs/ironoxide#116 implements it on BlockingIronOxide
As a Java developer
I want to have accessors of the form getXXX
so that the ironrust-java feels idiomatic in my Java application.
We are already using rust_swig's alias feature, so this should be really easy if we want to do it. This is somewhat at odds with the fact that the first planned usage of ironrust-java is actually from Scala. This probably only makes sense if we plan to wrap ironrust-java with a Scala QoL layer.
method document_encrypt_result::id(&self) -> String;
method document_encrypt_result::name(&self) -> Option<OurString>;
method document_encrypt_result::encrypted_data(&self) -> Vec<i8>; alias encryptedData;
method document_encrypt_result::created(&self) -> DateTime<Utc>; alias created;
method document_encrypt_result::last_updated(&self) -> DateTime<Utc>; alias lastUpdated;
becomes
method document_encrypt_result::id(&self) -> String; alias getId;
method document_encrypt_result::name(&self) -> Option<OurString>; alias getName;
method document_encrypt_result::encrypted_data(&self) -> Vec<i8>; alias getEncryptedData;
method document_encrypt_result::created(&self) -> DateTime<Utc>; alias getCreated;
method document_encrypt_result::last_updated(&self) -> DateTime<Utc>; alias getLastUpdated;
In theory, this should mean reproducing our ironoxide-java setup, but changing build.rs
to use Android specific rust_swig configurations.
For this issue, it is sufficient for an outside developer to be able to build an android library. It does not necessarily need to be published.
Propagate the changes made for ironoxide#78 and ironoxide#79.
Consuming ironoxide 0.19.0, all sdk methods should accept either a timeout
or a config
.
timeout
is an optional amount of time to run before returning an error.config
is a policy caching config and optional timeout for sdk operation timeoutAs an android developer
I want to see a basic example app with ironoxide-android integrated into it
so that I know how to integrate into my app.
Now that we have an AAR archive on maven, it should be simple to depend on ironoxide-android.
Not quite AC:
See IronCoreLabs/ironoxide#65 and IronCoreLabs/ironoxide#66.
From ironoxide's GroupCreateOpts
:
pub fn new(
id: Option<GroupId>,
name: Option<GroupName>,
add_as_admin: bool,
add_as_member: bool,
owner: Option<UserId>,
admins: Vec<UserId>,
members: Vec<UserId>,
needs_rotation: bool,
)
Take hand-built example and automate the build and publishing of the shared object.
RedHat (and the UBI Docker image) have their own numbering convention for OpenSSL libs. libironoxide-java.so
built on a typical Linux box won't run on RedHat due to runtime linker errors.
We should be able to add a RedHat-compatible build to our build matrix.
Some public types will need to have this foreign code added for equals()
and hashCode()
.
Reasoning/suggestion here
Consume IronCoreLabs/ironoxide#64
This is an epic to track Swift SDK support work.
Ironoxide-java doesn't have a changelog file like ironoxide and ironoxide-scala do. We should add one and backdate it as much as possible.
As an application developer
I want to be able to create a user's cryptographic identity ahead of them logging in
so that I can add them to groups and/or share data with them.
I also want to be able to see if a user needs rotation through user/verify
The current definition of the IronSdkAdvanced
struct (which is converted to a java class) can cause an issue where the underlying IronSdk can be garbage collected which causes all future calls to the IronSdkAdvanced
to core dump in strange ways.
Some of the errors (in case people are searching).
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NulError(96, [82, 101, 113, 117, 101, 115, 116, 32, 102, 97, 105, 108, 101, 100, 32, 119, 105, 116, 104, 32, 72, 84, 84, 80, 32, 115, 116, 97, 116, 117, 115, 32, 99, 111, 100, 101, 32, 39, 78, 111, 110, 101, 39, 32, 109, 101, 115, 115, 97, 103, 101, 32, 39, 70, 97, 105, 108, 101, 100, 32, 116, 111, 32, 101, 110, 99, 111, 100, 101, 32, 39, 49, 53, 55, 56, 57, 52, 49, 51, 49, 52, 49, 53, 55, 44, 49, 55, 57, 55, 44, 160, 114, 50, 229, 157, 127, 0, 0, 45, 54, 56, 102, 102, 45, 52, 97, 98, 53, 45, 57, 102, 49, 98, 45, 51, 55, 101, 55, 57, 57, 49, 100, 99, 49, 51, 57, 44, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 39, 32, 105, 110, 116, 111, 32, 97, 32, 88, 45, 73, 114, 111, 110, 67, 111, 114, 101, 45, 85, 115, 101, 114, 45, 67, 111, 110, 116, 101, 120, 116, 32, 104, 101, 97, 100, 101, 114, 39, 32, 97, 110, 100, 32, 99, 111, 100, 101, 32, 39, 69, 100, 101, 107, 84, 114, 97, 110, 115, 102, 111, 114, 109, 39])', src/libcore/result.rs:1165:5
thread '<unnamed>' panicked at 'Error when acquiring lock: poisoned lock: another task failed inside', /home/colt/.cargo/registry/src/github.com-1ecc6299db9ec823/recrypt-0.9.2/src/internal/mod.rs:1141:9
As a ironoxide-java user
I want to be able to configure the threading behavior of the library
so that I can tune the library for my use case
AC:
Instead of making ironoxide-java consumers manually call java.lang.System.loadLibrary
manually with the name of the ironoxide library, we should wrap that internally and do it similar to how it works with loading NaCl. Their code automatically attempts to find the library in various paths and loads it for the caller.
private static final class SingletonHolder {
public static final Sodium SODIUM_INSTANCE =
LibraryLoader.create(Sodium.class)
.search("/usr/local/lib")
.search("/opt/local/lib")
.search("lib")
.load(LIBRARY_NAME);
}
At a minimum, we'll want anything generated by rust_swig
to be in the same repo. The alternative is to have git submodules and let's not do that. There are options here, but the way I modeled this in my testing was to make a root directory called ironoxide-bindings
and then to have a Cargo.toml at that level like this:
[workspace]
members = [
"cpp",
"java",
"android"
]
Note that each subdirectory is its own Rust project with its own Cargo.toml except for the common
directory. Here was my directory structure (note, the cpp
directory is a little different from the cpp branch):
.
├── Cargo.lock
├── Cargo.toml
├── android
├── common
│ ├── chrono-include.rs
│ ├── jni_c_header.rs
│ ├── lib.rs
│ └── lib.rs.in
├── cpp
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ ├── headers
│ │ ├── CRustSlicei8.h
│ │ ├── Category.hpp
│ │ ├── ...
│ ├── src
│ │ └── lib.rs
├── java
│ ├── chrono-include.rs
│ └── jni_c_header.rs
├── swift
And note that cpp/src/lib.rs
has just this line std::include!("../../common/lib.rs");
The idea would be to build any given binding by switching to that directory, having a common directory, and any future dependencies could be path relative, for example by having all of the C/C++ headers in the cpp/headers
folder.
It looks like IronOxide itself can produce a library that works on iOS, according to this travis log. However, we need to be able to do this from the wrapper level. That is, we should be able to create a static library (crate-type = ["staticlib"]
) from the C wrapper. That wrapper has some extra dependencies in it.
My attempts to do this so far attempted to use cargo lipo to build the universal library, but that is hitting errors.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.