-
Notifications
You must be signed in to change notification settings - Fork 5
Development
- This is the public flavor.
- It should be always buildable without manual configurations.
- This flavor only contains a sample publisher.
- This is an internal product flavor, which cannot be build directly.
- Crashlytics is enabled.
Place the information required by the numbers backend in ./app/src/main/.../publisher/numbers_storage/Token.kt
. For example:
package io.numbersprotocol.starlingcapture.publisher.numbers_storage
const val baseUrl = "https://sample.com"
const val token = "token 0123456789abcdef"
- Debug
- LeakCanary is enabled.
- QA
- The quality of this build type should be product-ready. Thus, it should not contain any visible debugging artifacts (e.g. LeakCanary) except error messages.
- Kotlin
- Coroutine
- Flow
- AndroidX
- MVVM Architecture
- Android Architecture Component
- Paging Library
- Work Manager
- Preference Library
- Navigation Component
- Room Database
- Material Component
- Koin - dependecy injection
- Retrofit - networking
- Moshi - proof serialization
- Coil - image loading
- Timber - logging
- LeakCanary - memory leak detection
- The committed codes should pass all GitHub workflows.
- The committed codes should not have warnings from Android Studio linter. You can use
./gradlew lint
to verify. - The committed codes should not have memory leak reports by LeakCanary, which is enabled in the debug variant.
The name in string.xml
should match the English content in snake case. If the content of the string is a long message, the name should start with message_
. For example:
<string name="public_key_signature">Public Key Signature</string>
<string name="message_are_you_sure">The action cannot be undone.</string>
Currently, three types of media source are implemented:
- Internal camera (image)
- Internal camera (video)
- Canon Camera with CCAPI (image and video)
The components regarding media source should be placed in ./app/src/main/.../source/
.
Currently, we only use android-info-snapshot as information provider. The components regarding information collection should be placed in ./app/src/main/.../collector/information/
.
To add new information provider,
- Extends the
InformationProvider
. - Override the
provideInformation()
method. - Store the information to the DB with
InformationRepository
class.
Currently, two types of signature provider are implemented:
- AndroidOpenSSL (default signature)
- Zion signature (opt-in)
The components regarding information collection should be placed in ./app/src/main/.../collector/signature/
.
To add new signature provider,
- Extends the
SignatureProvider
. - Override the
provideSignature()
method. - Sign the
SortedProofInformation
from the given proof hash. - Store the signature to the DB with
SignatureRepository
class.
Currently, we only provide a sample publisher which does nothing.
The components regarding information collection should be placed in ./app/src/main/.../publisher/
.
To add new signature provider, see the SampleProofPublisher
class for details.
- Store the proof raw file into the internal directory.
- Store the hash of proof into proof repository.
- Collect information.
- Sign the proof and its collected information even if some information providers failed.
The SortedProofInformation
class provides the message of signature provider.
{
proof: {
hash: String,
mimeType: String,
timestamp: Long
},
information: [
{
provider: String,
name: String,
value: String
},
...
]
}
Example (beautified), Sign with Zion is disabled:
$ jq . information.json
{
"proof": {
"hash": "3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014",
"mimeType": "image/jpeg",
"timestamp": 1652606172402
},
"information": [
{
"provider": "InfoSnapshot",
"name": "Accelerometer",
"value": "[0.4421997, 6.9092345, 6.9160113]"
},
{
"provider": "InfoSnapshot",
"name": "Board",
"value": "QC_Reference_Phone"
},
{
"provider": "InfoSnapshot",
"name": "Brand",
"value": "Htc"
},
{
"provider": "InfoSnapshot",
"name": "Country",
"value": "United States"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Accuracy",
"value": "17.307"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Address",
"value": "No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Altitude",
"value": "27.399999618530273"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Bearing",
"value": "0.0"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Latitude",
"value": "24.9960048"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Longitude",
"value": "121.5104486"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Speed",
"value": "0.0"
},
{
"provider": "InfoSnapshot",
"name": "Current GPS Timestamp",
"value": "2022-05-15T09:16:13.438Z"
},
{
"provider": "InfoSnapshot",
"name": "Device Build Fingerprint",
"value": "Htc/bre2exdugl_00400/htc_bre2exdugl:8.1.0/OPM1.171019.011/200630:user/release-keys"
},
{
"provider": "InfoSnapshot",
"name": "Device Build ID",
"value": "1.15.709.1"
},
{
"provider": "InfoSnapshot",
"name": "Device Build Tags",
"value": "release-keys"
},
{
"provider": "InfoSnapshot",
"name": "Device Build Time",
"value": "6/30/20 8:16 PM"
},
{
"provider": "InfoSnapshot",
"name": "Device Build Type",
"value": "user"
},
{
"provider": "InfoSnapshot",
"name": "Device Name",
"value": "htc_bre2exdugl"
},
{
"provider": "InfoSnapshot",
"name": "End Product Name",
"value": "EXODUS 1s"
},
{
"provider": "InfoSnapshot",
"name": "Game Rotation Vector",
"value": "UNSUPPORTED"
},
{
"provider": "InfoSnapshot",
"name": "Geomagnetic Rotation Vector",
"value": "[0.4146733, -0.044002537, 0.09306122, 0.9041181, 0.0]"
},
{
"provider": "InfoSnapshot",
"name": "Gravity",
"value": "[1.7164232, 7.280239, 6.3422546]"
},
{
"provider": "InfoSnapshot",
"name": "Gyroscope",
"value": "UNSUPPORTED"
},
{
"provider": "InfoSnapshot",
"name": "Hardware",
"value": "qcom"
},
{
"provider": "InfoSnapshot",
"name": "Hash of Android ID",
"value": "0fa0b3f57c76d453433151b46ed2f6562bd31183f1e21d0c092318e519a9aed5"
},
{
"provider": "InfoSnapshot",
"name": "Language",
"value": "English"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Accuracy",
"value": "15.709"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Address",
"value": "No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Altitude",
"value": "27.399999618530273"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Bearing",
"value": "0.0"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Latitude",
"value": "24.996015"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Longitude",
"value": "121.5104355"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Speed",
"value": "0.0"
},
{
"provider": "InfoSnapshot",
"name": "Last Known GPS Timestamp",
"value": "2022-05-15T09:03:14.455Z"
},
{
"provider": "InfoSnapshot",
"name": "Light",
"value": "[6.0]"
},
{
"provider": "InfoSnapshot",
"name": "Linear Accelerometer",
"value": "[-1.2052132, -0.11499733, 0.21131894]"
},
{
"provider": "InfoSnapshot",
"name": "Magnetic Field",
"value": "[-0.09765625, -6.1523438, -77.83144]"
},
{
"provider": "InfoSnapshot",
"name": "Manufacturer",
"value": "HTC"
},
{
"provider": "InfoSnapshot",
"name": "Name",
"value": "English (United States)"
},
{
"provider": "InfoSnapshot",
"name": "Overall Product Name",
"value": "bre2exdugl_00400"
},
{
"provider": "InfoSnapshot",
"name": "Rotation Vector",
"value": "[0.4130853, -0.04073075, 0.08709024, 0.90559506, 0.0]"
},
{
"provider": "InfoSnapshot",
"name": "Script",
"value": ""
},
{
"provider": "InfoSnapshot",
"name": "Timestamp",
"value": "2022-05-15T09:16:22.898Z"
},
{
"provider": "InfoSnapshot",
"name": "Variant",
"value": ""
}
]
}
Example (raw), Sign with Zion is disabled:
$ cat information.json
{"proof":{"hash":"3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014","mimeType":"image/jpeg","timestamp":1652606172402},"information":[{"provider":"InfoSnapshot","name":"Accelerometer","value":"[0.4421997, 6.9092345, 6.9160113]"},{"provider":"InfoSnapshot","name":"Board","value":"QC_Reference_Phone"},{"provider":"InfoSnapshot","name":"Brand","value":"Htc"},{"provider":"InfoSnapshot","name":"Country","value":"United States"},{"provider":"InfoSnapshot","name":"Current GPS Accuracy","value":"17.307"},{"provider":"InfoSnapshot","name":"Current GPS Address","value":"No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"},{"provider":"InfoSnapshot","name":"Current GPS Altitude","value":"27.399999618530273"},{"provider":"InfoSnapshot","name":"Current GPS Bearing","value":"0.0"},{"provider":"InfoSnapshot","name":"Current GPS Latitude","value":"24.9960048"},{"provider":"InfoSnapshot","name":"Current GPS Longitude","value":"121.5104486"},{"provider":"InfoSnapshot","name":"Current GPS Speed","value":"0.0"},{"provider":"InfoSnapshot","name":"Current GPS Timestamp","value":"2022-05-15T09:16:13.438Z"},{"provider":"InfoSnapshot","name":"Device Build Fingerprint","value":"Htc/bre2exdugl_00400/htc_bre2exdugl:8.1.0/OPM1.171019.011/200630:user/release-keys"},{"provider":"InfoSnapshot","name":"Device Build ID","value":"1.15.709.1"},{"provider":"InfoSnapshot","name":"Device Build Tags","value":"release-keys"},{"provider":"InfoSnapshot","name":"Device Build Time","value":"6/30/20 8:16 PM"},{"provider":"InfoSnapshot","name":"Device Build Type","value":"user"},{"provider":"InfoSnapshot","name":"Device Name","value":"htc_bre2exdugl"},{"provider":"InfoSnapshot","name":"End Product Name","value":"EXODUS 1s"},{"provider":"InfoSnapshot","name":"Game Rotation Vector","value":"UNSUPPORTED"},{"provider":"InfoSnapshot","name":"Geomagnetic Rotation Vector","value":"[0.4146733, -0.044002537, 0.09306122, 0.9041181, 0.0]"},{"provider":"InfoSnapshot","name":"Gravity","value":"[1.7164232, 7.280239, 6.3422546]"},{"provider":"InfoSnapshot","name":"Gyroscope","value":"UNSUPPORTED"},{"provider":"InfoSnapshot","name":"Hardware","value":"qcom"},{"provider":"InfoSnapshot","name":"Hash of Android ID","value":"0fa0b3f57c76d453433151b46ed2f6562bd31183f1e21d0c092318e519a9aed5"},{"provider":"InfoSnapshot","name":"Language","value":"English"},{"provider":"InfoSnapshot","name":"Last Known GPS Accuracy","value":"15.709"},{"provider":"InfoSnapshot","name":"Last Known GPS Address","value":"No. 62, Anping Rd, Zhonghe District, New Taipei City, Taiwan 235"},{"provider":"InfoSnapshot","name":"Last Known GPS Altitude","value":"27.399999618530273"},{"provider":"InfoSnapshot","name":"Last Known GPS Bearing","value":"0.0"},{"provider":"InfoSnapshot","name":"Last Known GPS Latitude","value":"24.996015"},{"provider":"InfoSnapshot","name":"Last Known GPS Longitude","value":"121.5104355"},{"provider":"InfoSnapshot","name":"Last Known GPS Speed","value":"0.0"},{"provider":"InfoSnapshot","name":"Last Known GPS Timestamp","value":"2022-05-15T09:03:14.455Z"},{"provider":"InfoSnapshot","name":"Light","value":"[6.0]"},{"provider":"InfoSnapshot","name":"Linear Accelerometer","value":"[-1.2052132, -0.11499733, 0.21131894]"},{"provider":"InfoSnapshot","name":"Magnetic Field","value":"[-0.09765625, -6.1523438, -77.83144]"},{"provider":"InfoSnapshot","name":"Manufacturer","value":"HTC"},{"provider":"InfoSnapshot","name":"Name","value":"English (United States)"},{"provider":"InfoSnapshot","name":"Overall Product Name","value":"bre2exdugl_00400"},{"provider":"InfoSnapshot","name":"Rotation Vector","value":"[0.4130853, -0.04073075, 0.08709024, 0.90559506, 0.0]"},{"provider":"InfoSnapshot","name":"Script","value":""},{"provider":"InfoSnapshot","name":"Timestamp","value":"2022-05-15T09:16:22.898Z"},{"provider":"InfoSnapshot","name":"Variant","value":""}]}
signature.json
provides both a digital signature and a public key. The content of signature.json
does not equal to the digital signature of a Sorted Proof Information directly.
[
{
proofHash: Hex String, # raw asset's sha256
provider: String, # cryptographic signing algorithm provider
signature: Hex String, # cryptographic digital signature signed by the private key
publicKey: Hex String # cryptographic public key for verifying the signature above
},
...
]
Example (beautified), Sign with Zion is disabled:
$ jq . signature.json
[
{
"proofHash": "3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014",
"provider": "AndroidOpenSSL",
"signature": "304502203ced7a2eb4faee3422156066fd8da9afd8a851608f421340c437c3a1f0180fe7022100fdad1b273f5e4851077429ca4b692b223c9f20c0db5140a987aa2c6a86ea286b",
"publicKey": "3059301306072a8648ce3d020106082a8648ce3d03010703420004813afd7f6ba95fdebeac7812c7ab5af9ca59547b2a73f5aa75accca4e4ad2eb6849d4948a9fcfb8c2b890ba0dfbe4463bbfe4ac163981a93517bfb34598fc850"
}
]
Example (raw), Sign with Zion is disabled:
$ cat signature.json
[{"proofHash":"3eb44256eb98c9d43c48ed0dcbc660e8dafa9bdf54abf4da406846cea8311014","provider":"AndroidOpenSSL","signature":"304502203ced7a2eb4faee3422156066fd8da9afd8a851608f421340c437c3a1f0180fe7022100fdad1b273f5e4851077429ca4b692b223c9f20c0db5140a987aa2c6a86ea286b","publicKey":"3059301306072a8648ce3d020106082a8648ce3d03010703420004813afd7f6ba95fdebeac7812c7ab5af9ca59547b2a73f5aa75accca4e4ad2eb6849d4948a9fcfb8c2b890ba0dfbe4463bbfe4ac163981a93517bfb34598fc850"}]
The verification concept is that
- If Proof Information is trustworthy, the Asset checksum is trustworthy.
- If the Asset checksum is trustworthy, the Asset is trustworthy.
The Verification Tool and starling-capture-verification-examples.zip demonstrate the steps to verify the signatures.
verify.sh
is a wrapper of starling_capture_verifier.py
. If you want to assign the metadata (information.json) and signature (signature.json) individually, you can use starling_capture_verifier.py
.
$ cd util/verification/
$ unzip starling-capture-verification-examples.zip
$ ./verify.sh starling-capture-verification-examples/1.8.0/d7a07fafcbafceb5d626d673f0aabdb4db9d4ce6058f4e9859380831e556aa5a
Verification result: Pass
Summary:
SW key verification: True
HW key verification (Zion): False
HW key verification classic (Zion): False
HW session key verification (Zion): False
HW session key verification classic (Zion): True
Wallet Addresses:
Zion singer wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
Note
1. For the HW-related verifications, only one of them will be True.
$ ./verify.sh starling-capture-verification-examples/1.9.2/7e96c9fe16f96540de449a422852138d723c9ae80269fe4ae0e802323bf6ac7d
Verification result: Pass
Summary:
SW key verification: True
HW key verification (Zion): False
HW key verification classic (Zion): False
HW session key verification (Zion): True
HW session key verification classic (Zion): False
Wallet Addresses:
Zion singer wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
Recovered wallet address: 0x5f5ad77f4f924232a6e486216ddefba8a732b96b
Note
1. For the HW-related verifications, only one of them will be True.
Before v1.9.2, Starling Capture uses "classic" signature/verification. The signature and verification flow charts are below.
Zion signature and verification
Zion session-based signature and verification
Zion signature and verification classic (< v1.9.2)
Zion session-based signature and verification classic (< v1.9.2)
The known regression in v1.7.x (non-public pre-release) was due to that signatures were generated before the completion of HW metadata collection (#122). The issue was first introduced by commit a1f381df
on 12 Oct 2020 and fixed 11 days after (23 Oct 2020) by commit 5f53d87
.
Tips for verifying v1.7.0 metadata
-
Metadata (
information.json
) ends with "noeol"- Open Node.js
- Create metadata JSON object
- Save file by running
fs.writeFileSync("information.json", JSON.stringify(metadataObj))
-
Make value of the
information
key to be an empty list -
Make metadata look like
{"proof":{"hash":"8e57db457dfb242405f31122318990cac21450a4bfed424e722a964ede1fe8e8","mimeType":"image/jpeg","timestamp":1662967587804},"information":[]}
Please kindly be noted that since Starling Capture is a project to experiment with new concepts, fast iteration and sometimes unmatured technologies are expected. It is always safer to use the latest tagged version instead of the old versions and the code branches.