Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
mirceanis committed May 13, 2019
2 parents 86d8e16 + 968ea7c commit cca475e
Show file tree
Hide file tree
Showing 52 changed files with 4,650 additions and 63 deletions.
50 changes: 50 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
version: 2.1
jobs:
build:
docker:
- image: circleci/android:api-28-alpha

working_directory: ~/repo

environment:
# Customize the JVM maximum heap limit
JVM_OPTS: -Xmx3200m
TERM: dumb

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v2-dependencies-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle" }}
# fallback to using the latest cache if no exact match is found
- v2-dependencies-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-

- run: ./gradlew dependencies :signer:dependencies androidDependencies

- save_cache:
paths:
- ~/.gradle
key: v2-dependencies-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle" }}

# run tests!
- run: ./gradlew test

# store test results
- run:
name: Save test results
command: |
mkdir -p ~/test-results/junit/
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/junit/ \;
when: always
- store_test_results:
path: ~/test-results
- store_artifacts:
path: ~/test-results

workflows:
version: 2
workflow:
jobs:
- build
87 changes: 45 additions & 42 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
## Signer library has moved to [uport-android-sdk](https://github.com/uport-project/uport-android-sdk)

Please use that one directly. This repo is no longer maintained.

## Uport android signer

[![](https://jitpack.io/v/uport-project/uport-android-signer.svg)](https://jitpack.io/#uport-project/uport-android-signer)
[![CircleCI](https://circleci.com/gh/uport-project/uport-android-signer.svg?style=svg)](https://circleci.com/gh/uport-project/uport-android-signer)

This library is used to create and manage keys for uport account.
It supports creating keyPairs from seed phrases,
protecting these keys with authenticated encryption (android lock-screen / fingerprint),
Expand All @@ -13,7 +12,7 @@ Where available, keys and seeds created by this lib will be protected by
encryption backed by ARM Trusted Execution Environment (TEE).

Note: The curve used for ETH signing is not backed by the TEE,
therefore private keys exist in memory while in use but are encrypted with TEE keys while on storage.
therefore private keys exist in memory while in use but are encrypted with TEE keys at rest.

### Import

Expand All @@ -22,21 +21,17 @@ in your main `build.gradle`:
allprojects {
repositories {
...
//...
maven { url 'https://jitpack.io' }
}
}
```

[![](https://jitpack.io/v/uport-project/uport-android-signer.svg)](https://jitpack.io/#uport-project/uport-android-signer)

in your app `build.gradle`:
```groovy
uport_sdk_version = "v0.2.1"
uport_signer_version = "0.3.0"
dependencies {
...
~~implementation "com.github.uport-project:uport-android-signer:0.2.2"~~
implementation "com.github.uport-project.uport-android-sdk:signer:$uport_sdk_version"
//...
implementation "com.github.uport-project.uport-android-signer:signer:$uport_signer_version"
}
```

Expand All @@ -60,22 +55,25 @@ The options are:

> #### Important notes:
> * On KitKat, all `KeyProtection.Level` options default to `SIMPLE`
> * On Lolipop, the 30 second timeout window for `SINGLE_PROMPT` is not enforced by the AndroidKeyStore API, it is emulated by this library
> * On Lolipop, the 30 second timeout window for `SINGLE_PROMPT` is not enforced by the
`AndroidKeyStore` API, it is emulated by this library

#### Create a seed:

This creates a seed that is used for future key derivation and signing:
The seed is representable by a bip39 mnemonic phrase.

```kotlin
UportHDSigner().createHDSeed(activity, KeyProtection.Level.SIMPLE, { err, rootAddress, publicKey ->
//seed has been created and is accessible using rootAddress
// * the handle is `rootAddress`
// * the corresponding publicKey in base64 is `publicKey`
// * if there was an error, those are blank and the err object is non null

// To use the seed, refer to it using this `rootAddress`
})
UportHDSigner().createHDSeed(activity, KeyProtection.Level.SIMPLE, { err, seedHandle, publicKey ->
if (err != null) {
//handle error
} else {
//seed has been created and is accessible using seedHandle
// * the handle is `seedHandle` - save this so you can use the seed later
// * `publicKey` - a publicKey in base64 encoding,
// corresponding to the private key derived using the `UPORT_ROOT_DERIVATION_PATH` "m/7696500'/0'/0'/0'"
}
})
```

You can also import bip39 mnemonic phrases:
Expand All @@ -85,18 +83,18 @@ You can also import bip39 mnemonic phrases:
//bip39 mnemonic phrase:
val phrase = "vessel ladder alter ... glass valve picture"

UportHDSigner().importHDSeed(activity, KeyProtection.Level.SIMPLE, phrase, { err, rootAddress, publicKey ->

if (err != null) {
//handle error
} else {
assertEquals("0x794a...e96ac8", rootAddress)
//seed has been imported and
// * the handle is `rootAddress`
// * the corresponding publicKey in base64 is `publicKey`
}
})
UportHDSigner().importHDSeed(activity, KeyProtection.Level.SIMPLE, phrase, { err, seedHandle, publicKey ->

if (err != null) {
//handle error
} else {
assertEquals("0x794a...e96ac8", seedHandle)
//seed has been imported and
// * the handle is `seedHandle`
// * the corresponding publicKey in base64 is `publicKey`
}

})
```

#### Signing
Expand All @@ -105,13 +103,13 @@ You can use this lib to calculate ETH transaction signatures.
Building and encoding transaction objects into `ByteArray`s is not in the scope of this lib.

You can sign transactions using keys derived from a previously imported seed.
To refer to that seed you must use the `rootAddress` from the seed creation/import callback
To refer to that seed you must use the `seedHandle` from the seed creation/import callback
Based on the `KeyProtection.Level` used during seed import/creation, a prompt may be shown to the user
on the lock-screen / fingerprint dialog.

```kotlin

val rootAddress = "0x123..." //rootAddress received when creating/importing the seed
val seedHandle = "0x123..." //seedHandle received when creating/importing the seed

//bip32 key derivation
val derivationPath = "m/44'/60'/0'/0/0"
Expand All @@ -120,9 +118,9 @@ val derivationPath = "m/44'/60'/0'/0/0"
val txPayloadB64 = Base64.encodeToString( transaction.rlpEncode(), Base64.DEFAULT )

//gets shown to the user on fingerprint dialog or on lockscreen, based on `KeyProtection.Level` used
val prompt = "Please sign this transaction"
val prompt = "Unlock your key to sign this transaction"

UportHDSigner().signTransaction(activity, rootAddress, derivationPath, txPayloadB64, prompt, { err, sigData ->
UportHDSigner().signTransaction(activity, seedHandle, derivationPath, txPayloadB64, prompt, { err, sigData ->
if (err != null) {
//handle error
} else {
Expand All @@ -144,9 +142,11 @@ Also, do note that in the current version of this API,

```kotlin

UportHDSigner().signJwtBundle(activity, rootAddress, derivationPath, data, prompt, { err, sigData ->
val prompt = "Unlock your key to sign this credential"

UportHDSigner().signJwtBundle(activity, seedHandle, derivationPath, data, prompt, { err, sigData ->
if (err != null) {
//handle error
//process the error
} else {
//use sigData r,s,v components
}
Expand All @@ -157,8 +157,11 @@ UportHDSigner().signJwtBundle(activity, rootAddress, derivationPath, data, promp

### Changelog

### 0.3.0
* key management codebase moved back to this repo
* [breaking] updated to kotlin 1.3.x, kethereum 0.75.1 - will require some import changes

#### latest
#### v0.2.x
* *the signer library has moved to [uport-android-sdk](https://github.com/uport-project/uport-android-sdk)*

#### v0.2.2
Expand All @@ -180,4 +183,4 @@ UportHDSigner().signJwtBundle(activity, rootAddress, derivationPath, data, promp
* to make the `v` recovery param available to calling classes, JWT signing produces `SignatureData` instead of a JOSE encoded signature String

#### v0.0.1
* initial release
* initial release
100 changes: 91 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
buildscript {
ext {
kotlin_version = "1.2.61"
android_tools_version = "3.3.0-alpha07"
kotlin_version = "1.3.31"
android_tools_version = '3.4.0'
coroutines_version = "1.2.1"

build_tools_version = "27.0.3"
build_tools_version = "28.0.3"

min_sdk_version = 19
compile_sdk_version = 27
compile_sdk_version = 28
target_sdk_version = compile_sdk_version

support_lib_version = "27.1.1"
support_lib_version = "28.0.0"
constraint_layout_version = "1.1.3"

test_runner_version = "1.0.2"
test_rules_version = test_runner_version
test_orchestrator_version = test_runner_version
espresso_version = "3.0.2"
junit_version = "4.12"
mockito_version = "2.12.0"
constraint_layout_version = "1.1.2"
mockk_version = "1.9.3"
assertk_version = "0.12"
detekt_version = "1.0.0-RC14"

kethereum_version = "0.53"
uport_sdk_version = "v0.2.1"
spongycastle_version = "1.58.0.0"
kethereum_version = "0.75.1"
kotlin_common_version = "0.1.1"

current_release_version = "0.3.0"
}

repositories {
Expand All @@ -31,6 +37,36 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.dcendents:android-maven-gradle-plugin:2.1"
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"

classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detekt_version"
}
}

plugins {
id "io.errorlab.gradle.vault" version "0.1.0"
}

apply plugin: "io.gitlab.arturbosch.detekt"

detekt {
version = detekt_version
input = files(
"$projectDir"
)
//config = "${projectDir}/detekt.yml"
filters = ".*test.*,.*/resources/.*,.*/tmp/.*,.*/build/.*"
parallel = true
reports {
xml {
enabled = true
destination = file("${project.buildDir}/reports/detekt.xml")
}
html {
enabled = true
destination = file("${project.buildDir}/reports/detekt.html")
}
}
}

Expand All @@ -41,8 +77,54 @@ allprojects {

maven { url 'https://jitpack.io' }
}

//address warnings about multiple kotlin runtimes in classpath
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module("org.jetbrains.kotlin:kotlin-stdlib-jre7") because "warning about multiple runtimes in the classpath" with module("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
substitute module("org.jetbrains.kotlin:kotlin-stdlib-jre8") because "warning about multiple runtimes in the classpath" with module("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")

}
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'org.jetbrains.kotlin' && requested.name in [
'kotlin-reflect', 'kotlin-stdlib', 'kotlin-stdlib-common',
'kotlin-stdlib-jdk7', 'kotlin-stdlib-jdk8',
]) {
details.useVersion kotlin_version
}
}
}
}

subprojects { subproject ->

afterEvaluate {

if (subproject.plugins.hasPlugin("com.android.application") || subproject.plugins.hasPlugin("com.android.library")) {
subproject.android {
packagingOptions {
exclude "META-INF/main.kotlin_module"
exclude "META-INF/atomicfu.kotlin_module"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
}

subproject.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
}

apply from: "publishing.gradle"

task clean(type: Delete) {
delete rootProject.buildDir
}
1 change: 0 additions & 1 deletion demoapp/.gitignore

This file was deleted.

Loading

0 comments on commit cca475e

Please sign in to comment.