Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce uniffi module and Swift wrapper #173

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ categories = ["cryptography", "database"]
keywords = ["hyperledger", "aries", "ssi", "verifiable", "credentials"]
rust-version = "1.65"

[[bin]]
name = "uniffi-bindgen"
path = "uniffi/uniffi-bindgen.rs"
required-features = ["uffi"]

[lib]
name = "aries_askar"
path = "src/lib.rs"
Expand All @@ -28,13 +33,17 @@ rustdoc-args = ["--cfg", "docsrs"]
default = ["all_backends", "ffi", "logger", "migration"]
all_backends = ["postgres", "sqlite"]
ffi = ["ffi-support", "logger"]
uffi = ["uniffi", "all_backends", "logger", "tokio", "ffi"]
jemalloc = ["jemallocator"]
logger = ["env_logger", "log", "askar-storage/log"]
postgres = ["askar-storage/postgres"]
sqlite = ["askar-storage/sqlite"]
pg_test = ["askar-storage/pg_test"]
migration = ["askar-storage/migration"]

[build-dependencies]
uniffi = { version = "0.24.3", features = ["build", "cli", "tokio"] }

[dependencies]
async-lock = "2.5"
env_logger = { version = "0.9", optional = true }
Expand All @@ -45,6 +54,8 @@ once_cell = "1.5"
serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.11"
serde_json = "1.0"
tokio = { version = "1.5", optional = true }
uniffi = { version = "0.24.3", optional = true, features = ["cli", "tokio"] }
zeroize = "1.5"

[dependencies.askar-crypto]
Expand Down
119 changes: 119 additions & 0 deletions build-swift-framework.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/bin/sh

set -eo pipefail

NAME="aries_askar"
VERSION=$(cargo generate-lockfile && cargo pkgid | sed -e "s/^.*#//")
BUNDLE_IDENTIFIER="org.hyperledger.$NAME"
LIBRARY_NAME="lib$NAME.a"
FRAMEWORK_LIBRARY_NAME=${NAME}FFI
FRAMEWORK_NAME="$FRAMEWORK_LIBRARY_NAME.framework"
XC_FRAMEWORK_NAME="$FRAMEWORK_LIBRARY_NAME.xcframework"
HEADER_NAME="${NAME}FFI.h"
OUT_PATH="out"
MIN_IOS_VERSION="15.0"
WRAPPER_PATH="wrappers/swift/Askar/Sources/Askar"

AARCH64_APPLE_IOS_PATH="./target/aarch64-apple-ios/release"
AARCH64_APPLE_IOS_SIM_PATH="./target/aarch64-apple-ios-sim/release"
X86_64_APPLE_IOS_PATH="./target/x86_64-apple-ios/release"
AARCH64_APPLE_DARWIN_PATH="./target/aarch64-apple-darwin/release"
X86_64_APPLE_DARWIN_PATH="./target/x86_64-apple-darwin/release"

targets=("aarch64-apple-ios" "aarch64-apple-ios-sim" "x86_64-apple-ios" "aarch64-apple-darwin" "x86_64-apple-darwin")

# Build for all targets
for target in "${targets[@]}"; do
echo "Building for $target..."
rustup target add $target
cargo build --release --no-default-features --features uffi --target $target
done

# Generate swift wrapper
echo "Generating swift wrapper..."
mkdir -p $OUT_PATH
CURRENT_ARCH=$(rustc --version --verbose | grep host | cut -f2 -d' ')
cargo run --features uffi --bin uniffi-bindgen generate uniffi/askar.udl --language swift -o $OUT_PATH --lib-file ./target/$CURRENT_ARCH/release/$LIBRARY_NAME

# Merge libraries with lipo
echo "Merging libraries with lipo..."
lipo -create $AARCH64_APPLE_IOS_SIM_PATH/$LIBRARY_NAME \
$X86_64_APPLE_IOS_PATH/$LIBRARY_NAME \
-output $OUT_PATH/sim-$LIBRARY_NAME
lipo -create $AARCH64_APPLE_DARWIN_PATH/$LIBRARY_NAME \
$X86_64_APPLE_DARWIN_PATH/$LIBRARY_NAME \
-output $OUT_PATH/macos-$LIBRARY_NAME

# Create framework template
rm -rf $OUT_PATH/$FRAMEWORK_NAME
mkdir -p $OUT_PATH/$FRAMEWORK_NAME/Headers
mkdir -p $OUT_PATH/$FRAMEWORK_NAME/Modules
cp $OUT_PATH/$HEADER_NAME $OUT_PATH/$FRAMEWORK_NAME/Headers
cat <<EOT > $OUT_PATH/$FRAMEWORK_NAME/Modules/module.modulemap
framework module $FRAMEWORK_LIBRARY_NAME {
umbrella header "$HEADER_NAME"

export *
module * { export * }
}
EOT

cat <<EOT > $OUT_PATH/$FRAMEWORK_NAME/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$FRAMEWORK_LIBRARY_NAME</string>
<key>CFBundleIdentifier</key>
<string>$BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$FRAMEWORK_LIBRARY_NAME</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$VERSION</string>
<key>NSPrincipalClass</key>
<string></string>
<key>MinimumOSVersion</key>
<string>$MIN_IOS_VERSION</string>
</dict>
</plist>
EOT

# Prepare frameworks for each platform
rm -rf $OUT_PATH/frameworks
mkdir -p $OUT_PATH/frameworks/sim
mkdir -p $OUT_PATH/frameworks/ios
mkdir -p $OUT_PATH/frameworks/macos
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/sim/
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/ios/
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/macos/
mv $OUT_PATH/sim-$LIBRARY_NAME $OUT_PATH/frameworks/sim/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME
mv $OUT_PATH/macos-$LIBRARY_NAME $OUT_PATH/frameworks/macos/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME
cp $AARCH64_APPLE_IOS_PATH/$LIBRARY_NAME $OUT_PATH/frameworks/ios/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME

# Create xcframework
echo "Creating xcframework..."
rm -rf $OUT_PATH/$XC_FRAMEWORK_NAME
xcodebuild -create-xcframework \
-framework $OUT_PATH/frameworks/sim/$FRAMEWORK_NAME \
-framework $OUT_PATH/frameworks/ios/$FRAMEWORK_NAME \
-framework $OUT_PATH/frameworks/macos/$FRAMEWORK_NAME \
-output $OUT_PATH/$XC_FRAMEWORK_NAME

# Copy swift wrapper
# Need some temporary workarounds to compile swift wrapper
# https://github.com/rust-lang/cargo/issues/11953
cat <<EOT > $OUT_PATH/import.txt
#if os(macOS)
import SystemConfiguration
#endif
EOT
cat $OUT_PATH/import.txt $OUT_PATH/$NAME.swift > $WRAPPER_PATH/$NAME.swift
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
uniffi::generate_scaffolding("./uniffi/askar.udl").unwrap();
}
2 changes: 1 addition & 1 deletion src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mod log;
mod result_list;
mod secret;
mod store;
mod tags;
pub(crate) mod tags;

#[cfg(all(feature = "migration", feature = "sqlite"))]
mod migration;
Expand Down
22 changes: 21 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Secure storage designed for Hyperledger Aries agents

#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![deny(missing_docs, rust_2018_idioms)]

#[macro_use]
mod error;
Expand All @@ -24,7 +24,27 @@ pub use askar_storage::future;
#[cfg(feature = "ffi")]
mod ffi;

#[cfg(feature = "uffi")]
mod uffi;

pub mod kms;

mod store;
pub use store::{entry, PassKey, Session, Store, StoreKeyMethod};

#[cfg(feature = "uffi")]
pub use storage::entry::{Entry, EntryOperation, EntryTag, Scan, TagFilter};

#[cfg(feature = "uffi")]
pub use uffi::{
crypto::{AskarCrypto, AskarEcdhEs, AskarEcdh1PU},
error::ErrorCode,
entry::{AskarEntry, AskarKeyEntry},
key::{AskarLocalKey, AskarKeyAlg, SeedMethod, LocalKeyFactory, EncryptedBuffer},
scan::AskarScan,
session::{AskarSession, AskarEntryOperation},
store::{AskarStore, AskarStoreManager},
};

#[cfg(feature = "uffi")]
uniffi::include_scaffolding!("askar");
Loading
Loading