1
0
Форкнуть 0
An SDK to manage your Decentralized Identities and Verifiable Credentials.
Перейти к файлу
Sydney cba2686bfe
Create azure-pipeline.yml
2020-06-02 15:05:48 -04:00
.github Update issue templates 2020-05-14 12:57:44 -04:00
.idea Integrate rooms database to store long form id 2020-04-04 15:27:53 -07:00
PortableIdentityCard-ClientSDK Add Experiemental Tag to self-attested claims 2020-05-29 10:12:36 -07:00
gradle/wrapper Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00
.gitignore Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00
CODE_OF_CONDUCT.md Initial CODE_OF_CONDUCT.md commit 2020-02-05 13:51:57 -08:00
LICENSE Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00
PULL_REQUEST_TEMPLATE.md adding pull request template 2020-03-13 10:03:56 -04:00
README.md Update from Eric's comments 2020-05-29 11:35:54 -07:00
SECURITY.md Initial SECURITY.md commit 2020-02-05 13:51:58 -08:00
azure-pipeline.yml Create azure-pipeline.yml 2020-06-02 15:05:48 -04:00
build.gradle Cleanup dependencies 2020-05-09 07:54:22 -07:00
gradle.properties Cleanup gradle dependencies 2020-05-09 08:23:23 -07:00
gradlew Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00
gradlew.bat Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00
settings.gradle Port kotlin SDK to new Android project 2020-02-05 18:48:09 -08:00

README.md

Build status

This SDK is used in the Microsoft Authenticator app in order to interact with verifiable credentials and DIDs on the ION network.

Verifiable Credentials

Verifiable credentials are a W3C standard format that can be used to validate information about people, organizations, and more. Verifiable credentials put people in control of their personal information, enabling more trustworthy digital experiences while respecting people's privacy.

To learn more about verifiable credentials, please review our documentation.

How to use SDK

Initializing SDK

PortableIdentitySdk - this class is used to initialize the SDK inside of the app with these init method parameters:

init(
        context: Context, // App Context.
        logConsumerBridge: SdkLog.ConsumerBridge = DefaultLogConsumerBridge(), // Bridge for logging.
        registrationUrl: String = "", // Registration url for registering Identifier (not needed for MVP)
        resolverUrl: String = "https://beta.discover.did.microsoft.com/1.0/identifiers" // Resolver url for resolving Identifiers.
    )

Example of SDK initialization within app:

val piSdk = PortableIdentitySdk.init(getApplicationContext(), new PortableIdentitySdkLogConsumerBridge());

note: Dependency Injection is configured through Dagger in our SDK.

External facing APIs

There two classes that are external to our SDK.

Identifier Manager

IdentifierManager - this class deals with any logic related to Identifiers such as creating Identifiers, creating Pairwise Identifiers, and resolving Identifiers through the Resolver.

Creating and saving Identifier Example:

val identifier = identifierManager.initLongFormIdentifier()

To get master Identifier

val identifier = identifierManager.getIdentifier()

note: Personas Identifiers to come.

Pairwise Identifiers

Pairwise Identifier are Identifiers created from four things:

  • An Identifier (in our case, the Master Identifier)
  • A target string (in our case, the relying party DID)
  • The algorithm of the keys that will be generated for the Identifier
  • The key type of the keys that will be generated for the Identifier

Pairwise Identifiers are created for every interaction with a relying party to prevent to Relying Parties from correlating users based off of Identifiers.

Card Manager

CardManager - this class deals with any logic related to Portable Identity Cards such as requesting a card through the Issuance service, presenting Verifiable Credentials back to relying parties, and saving cards.

Issuance Flow Example:

// to get a new issuance request from a contract url
val request = cardManager.getIssuanceRequest(url)

// create issuance response.
val response = cardManager.createIssuanceResponse(request)
// add requested verifiable credentials to response.
addCollectedRequirementsToResponse(response, requirementList)
// get Master Identifier.
val identifier = identifierManager.getMasterIdentifier()
// create a pairwise identifier for connection from master identifier and requester's identifier.
val pairwiseIdentifier = identifierManager.createPairwiseIdentifier(identifier, request.entityIdentifier)
// send issuance response in order to get a verifiable credential, signed by pairwise identifier. 
val card = cardManager.sendIssuanceResponse(response, pairwiseIdentifier)
// save card to database.
cardManager.saveCard(card)

Presentation Flow Example:

// to get a new presentation request from a openid:// scanned through QRCode or deeplink
val request = cardManager.getPresentationRequest(url)

// create and send presentation response.
val response = cardManager.createPresentationResponse(request)
// add requested verifiable credentials to response.
addCollectedRequirementsToResponse(response, requirementList)
// get Master Identifier.
val identifier = identifierManager.getMasterIdentifier()
// create a pairwise identifier for connection from master identifier and requester's identifier.
val pairwiseIdentifier = identifierManager.createPairwiseIdentifier(identifier, request.entityIdentifier)
// send response to relying party the initiated request, signed by pairwise identifier.
// if successful, create and store receipts of interaction with the relying party for each verifiable credential that was presented.
cardManager.sendPresentationResponse(response, pairwiseIdentifier)

Get all saved Portable Identity Cards

val cards = cardManager.getCards()

note: Every method is wrapped in a Result object. Unwrapping these returns is not included in these examples to simplify things a bit. (see Result Class Section for more details)

OIDC Formatter and Validator

OIDC Response Formatter

A OidcResponseFormatter object creates a token payload based on the OpenID Connect Protocol (Self-Issued token) with an addition of a attestations claim that is not yet standard. This attestations claim contains all verifiable credentials, id-tokens, or self-attested claims that the initial request asked for. Then the payload is signed with the keys owned by the responder Identifier.

note: OIDC Self-Issued Protocol is the only protocol we support as of now in the OidcResponseFormatter class.

Presentation Request Validator

PresentationRequestValidator object takes in a PresentationRequest and validates the request based on protocol.

interface PresentationRequestValidator {
    suspend fun validate(request: PresentationRequest)
}

note: OIDC Self-Issued Protocol is the only protocol we support as of now in OidcRequestValidator class.

Portable Identity Card Data Model

Portable Identity Cards are simply a container for verifiable credentials and are comprised of:

data class PortableIdentityCard (

    val id: String,

    val verifiableCredential: VerifiableCredential,

    val displayContract: DisplayContract
)

note: this data model will change when pairwise feature is implemented.

Receipts

A Receipt is created for every verifiable credential that is presented. The purpose of a Receipt is to keep track of when a verifiable credential was presented and who that vc was presented to.

data class Receipt (
    val id: Int,

    // Issuance or Presentation
    val action: ReceiptAction,

    // did of the verifier/issuer
    val entityIdentifier: String,

    // date action occurred
    val activityDate: Long,

    //Name of the verifier/issuer
    val entityName: String,

    val cardId: String
)

Repository Layer

The repository is an abstraction layer that is consumed by business logic and abstracts away the various data sources that an app can have. There are two datasources in our SDK: network and database.

CardRepository - this class saves Portable Identity Cards and Receipts to the database, retrieves cards and receipts from the database, GETs presentation and issuance requests, and POSTs presentation and issuance responses.

IdentifierRepository - this class save Identifiers to database, retrieves Identifiers from database, and resolves Identifiers.

note: we are using Room for database access and Retrofit for network calls.

Crypto Layer

CryptoOperations - this class is the top layer of our crypto abstractions.

Initialized like so:

class CryptoOperations (
    subtleCrypto: SubtleCrypto,
    val keyStore: KeyStore
)
  • SubtleCrypto - interface of the Web Crypto API that provides a number of low-level cryptographic functions
  • KeyStore - where keys are stored, default implementation is AndroidKeyStore.

Crypto methods exposed in cryptoOperations layer

fun sign(payload: ByteArray, signingKeyReference: String, algorithm: Algorithm? = null)
fun verify(payload: ByteArray, signature: ByteArray, signingKeyReference: String, algorithm: Algorithm? = null)
fun encrypt() // TODO
fun decrypt() // TODO
fun generateKeyPair(keyReference: String, keyType: KeyType)
fun generatePairwise(seed: String)
fun generateSeed(): String

Result Class

Every external method returns a Result for error handling simplicity.

sealed class Result<out S> {
    class Success<out S>(val payload: S) : Result<S>()
    class Failure(val payload: PortableIdentitySdkException) : Result<Nothing>()
}

If the method was successful, Result.Success(ReturnType) is returned. If an exception occurred, Result.Failure(PortableIdentityCardException) is returned.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.