Requirements & supported platforms

The Tanker Client is available on Linux, MacOs, and Windows. Note that go 1.12 or higher is required. Also, because the client is built with cgo, you need a C compiler to use the Go package.

Linux

gcc-8 or higher is supported

macOS

You should install latest XCode version, then make sure command line tools are installed by running xcode-select --install

Windows

You should install MinGW-6 and configure cgo to target a 32 bits architecture:

set GOARCH=386
set CGO_ENABLED=1
go build ./...

Usage

Import the package, and build you project.

import (
    "github.com/TankerHQ/sdk-go/v2/core"
)

Error handling

Error is the Tanker error interface. Cast the error returned by Tanker functions to this interface to get the Code associated with the error:

tanker, err := core.CreateTanker(opts)
if tankerErr, ok := err.(core.Error); ok {
        fmt.Printf("CreateTanker failed with code: %i", tankerErr.Code())
}

Here is the list of possible error codes:

type ErrorCode uint32

const (
    ErrorInvalidArgument ErrorCode = iota + 1
    ErrorInternalError
    ErrorNetworkError
    ErrorPreconditionFailed
    ErrorOperationCanceled

    ErrorDecryptionFailed

    ErrorGroupTooBig

    ErrorInvalidVerification
    ErrorTooManyAttempts
    ErrorExpiredVerification
    ErrorIoError
)
Error Description
ErrorDecryptionFailed A decryption operation failed
ErrorExpiredVerification The identity verification is expired
ErrorGroupTooBig The group would exceed the maximum member limit (1000)
ErrorInternalError Tanker internal error, thrown as a last resort
ErrorInvalidArgument Developer error, one of the function's argument is invalid
ErrorInvalidVerification An invalid identity verification was provided
ErrorNetworkError Network error, e.g. connection lost or the Tanker server is not reachable
ErrorOperationCanceled An asynchronous operation was canceled when Tanker stopped
ErrorPreconditionFailed Developer error, a function's precondition was violated
ErrorTooManyAttempts An operation was attempted too many times, please try again later
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore
ErrorConflict There was a conflict with a concurrent operation from another device/user, try again

NewTanker

Create a new Tanker instance.

session, err := core.NewTanker(core.TankerOptions{"<your app ID>", "/home/user/.config/fancyname/", nil})
Parameters Description
options: TankerOptions The options needed to create a new Tanker instance
options.AppId: string The Application ID you want to use
options.WritablePath: string An existing filesystem path to store persistent user data. This path should be the same for a given device.
options.Url: *string The url of the Tanker service. Should be left to nil

Session management

Start

Starts a Tanker session and returns a status. See the Starting a Tanker Session guide for more details.

The Tanker status must be StatusStopped before calling Start().

func (t *Tanker) Start(identity string) (Status, error)
Parameters
identity: string A Tanker identity
Returns
StatusReady The session is ready and fully operational
StatusIdentityRegistrationNeeded First use of the identity. registerIdentity() must be called.
StatusIdentityVerificationNeeded New device for this identity. verifyIdentity() must be called.
Errors Description
ErrorInvalidVerification An argument is ill-formed
ErrorPreconditionFailed The session is not STOPPED

Stop

Stops the current Tanker session. This session can either be destroyed with Destroy() or be restarted with Start().

func (t *Tanker) Stop() error

Destroy

Destroys this Tanker instance. This functions performs internal resources cleanups and calls Stop() if necessary. No further operations is possible on this instance after calling Destroy(), you'll need to create a new instance.

func (t *Tanker) Destroy() error

GetStatus

The following constants are available to check the Status value:

Status Description
StatusStopped The session is stopped. Start() can be called on it.
StatusReady The session is ready and fully operational
StatusIdentityRegistrationNeeded The session needs the identity to be verified to become StatusReady
StatusIdentityVerificationNeeded This identity is not associated with any verification method. One must be registered.

You can read the Status of the Tanker session using:

func (t *Tanker) GetStatus() Status

Identity verification

Verification

A Verification object is typically used to perform an identity verification, or to register a new identity verification method.

EmailVerification

type EmailVerification struct {
    Email            string
    VerificationCode string
}

The VerificationCode is provided to the user by email and must be used here with the Email address.

KeyVerification

type KeyVerification struct {
    Key string
}

The unlock key generated by the user should be used here.

OidcVerification

type OidcVerification struct {
    OidcIdToken string
}

The Open ID Connect ID token registered by the user should be used here.

PassphraseVerification

type PassphraseVerification struct {
    Passphrase string
}

The verification password registered by the user should be used here.

VerificationMethod

VerificationMethod describes a type of method registered on the Tanker Server by a user. It may contains the email registered if Type is a VerificationMethodEmail.

type VerificationMethod struct {
    Type  VerificationMethodType
    Email *string
}

VerificationMethodType

This enumeration represents the different identity verification methods available.

VerificationMethodType Description
VerificationMethodEmail The user is verified with a token sent through a link in an email
VerificationMethodPassphrase The user sets a password. Full end-to-end verification method
VerificationMethodVerificationKey The user is verified with a verification key
VerificationMethodOidcIdToken The user is verified with OpenID Connect

RegisterIdentity

Registers the user's identity with which Start() has been called, and starts the session.

The Tanker status must be StatusIdentityRegistrationNeeded.

func (t *Tanker) RegisterIdentity(verification interface{}) error
Parameters
verification: Verification The verification to use for identity registration
Errors Description
ErrorPreconditionFailed The status is not StatusIdentityRegistrationNeeded
ErrorExpiredVerification The verification expired
ErrorInvalidVerification The verification is invalid
ErrorTooManyAttempts Too many verification attempts occurred. Please retry later.

VerifyIdentity

Verifies the user's identity with which Start has been called, and starts the session.

The Tanker status must be StatusIdentityVerificationNeeded.

func (t *Tanker) VerifyIdentity(verification interface{}) error

This function verifies the user's identity based on the provided verification. It must be called when the user has started a Tanker session on a new device.

Parameters
verification: Verification The verification to use
Errors Description
ErrorPreconditionFailed The status is not StatusIdentityVerificationNeeded
ErrorExpiredVerification The verification expired
ErrorInvalidVerification The verification is invalid
ErrorTooManyAttempts Too many verification attempts occurred. Please retry later.
ErrorConflict There was a conflict with a concurrent operation from another device/user, try again

SetVerificationMethod

Adds or overrides a verification method.

The Tanker status must be StatusReady.

func (t *Tanker) SetVerificationMethod(verification interface{}) error
Parameters
verification: Verification The verification to use
Errors Description
ErrorExpiredVerification The verification expired
ErrorInvalidVerification The verification is invalid
ErrorPreconditionFailed The status is not StatusReady
ErrorTooManyAttempts Too many verification attempts occurred. Please retry later.
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

GetVerificationMethods

Returns the list of registered verification methods available to the user.

The Tanker status must be either StatusIdentityVerificationNeeded or StatusReady.

func (t *Tanker) GetVerificationMethods() ([]VerificationMethod, error)
Returns
[]VerificationMethod The list of VerificationMethods already set
Errors Description
ErrorPreconditionFailed The status is neither StatusIdentityVerificationNeeded nor StatusReady

GenerateVerificationKey

Generates a verification key, registers its public part on Tanker's servers, and returns its private part, which is required to verify the user's identity.

The Tanker status must be StatusIdentityRegistrationNeeded.

func (t *Tanker) GenerateVerificationKey() (*string, error)

Once the verification key has been generated, it is not possible to set up high-level verification methods (e.g. email/passphrase).

The opposite is also true: no high-level verification method must have been set up before calling this function.

It is NOT possible to generate several verification keys.

Warning

This is a low level function for specific use-cases only, as it can have severe security implications. Use it only if high-level identity verification doesn't fit your needs, and you fully understand how it works. Don't hesitate to contact us for help.

Returns
*string The generated verification key
Errors Description
ErrorPreconditionFailed The session is not in the StatusIdentityRegistrationNeeded state

Device management

GetDeviceId

Retrieves the current device's ID.

func (t *Tanker) GetDeviceID() (*string, error)

Each device has its own ID and can be identified as such.

Returns
*string The current device's ID
Errors Description
ErrorPreconditionFailed The status is not StatusReady

GetDeviceList

Retrieves the user's devices list.

The Tanker status must be StatusReady.

func (t *Tanker) GetDeviceList() (goDevices []DeviceDescription, err error)
Returns
[]DeviceDescription The list of devices

Each DeviceDescription is a structure describing a device, with the following fields:

Method Description
DeviceID string The device ID of the device
IsRevoked bool true if the device has been revoked
Errors Description
ErrorPreconditionFailed The status is not StatusReady
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

RevokeDevice

Revokes one of the user's devices.

func (t *Tanker) RevokeDevice(deviceID string) (err error)
Parameters
deviceId: string The device ID of the device to be revoked
Errors Description
ErrorPreconditionFailed The status is not StatusReady
ErrorInvalidArgument The specified device was not found
ErrorInvalidArgument Cannot revoke another user's device
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore
ErrorConflict There was a conflict with a concurrent operation from another device/user, try again

Encryption

Encrypt

func (t *Tanker) Encrypt(clearData []byte, options *EncryptOptions) ([]byte, error)

Encrypt encrypts the passed []byte and returns the result.

Encrypts a byte[] of raw data and returns the result. To share the resulting encrypted resource with either or both individuals and groups, fill the EncryptOptions parameter.

Parameters
clearData: byte[] The clear data to be encrypted. Can be either a java byte[] or a Kotlin ByteArray.
options: EncryptOptions Encryption and sharing options (optional)
Returns
byte[] The encrypted data
Errors Description
ErrorInvalidArgument A recipient (user or group) was not found
ErrorPreconditionFailed The status is not StatusReady
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

EncryptOptions

The EncryptOptions allows you to specify who will be able to decrypt the resource through the shareWithUsers() and shareWithGroups() methods.

If neither are specified, only the resource creator will be able to decrypt it.

In general, if you need to share a resource with multiple users, it is advised to create groups and use the Groups field.

Fields Description
Recipients []string User public identities to share with (the current user's identity will be automatically appended)
Groups []string Group IDs to share with

Decrypt

func (t *Tanker) Decrypt(encryptedData []byte) ([]byte, error)

Decrypts a resource and returns the original clear data.

Parameters
data: []byte The encrypted data to be decrypted
Returns
[]byte The decrypted data
Errors Description
ErrorPreconditionFailed The status is not StatusReady
ErrorDecryptionFailed The encrypted data is corrupted
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

Groups management

CreateGroup

func (t *Tanker) CreateGroup(publicIdentities []string) (*string, error)

Creates a Tanker group. The group will be created with the user's PublicIdentities provided. This function succeeds or fails completely, e.g. if a PublicIdentity is invalid, no group is created. On success, the created group ID is returned.

Note

The maximum number of users per group is 1000.

Parameters
publicIdentities: []string Group members' public identities
Returns
*string A future of the newly created group's ID
Errors Description
ErrorInvalidArgument Some recipients (groups or users) have not been found. The whole operation is canceled
ErrorPreconditionFailed The status is not StatusReady
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

UpdateGroupMembers

Add members to an existing group.

func (t *Tanker) UpdateGroupMembers(groupID string, publicIdentitiesToAdd []string) error

The new group members will automatically get access to all resources previously shared with the group.

Parameters
groupId: string Group ID to modify
usersToAdd: []string Public identities of users to add to the group
Errors Description
ErrorInvalidArgument One of the arguments is ill-formed
ErrorPreconditionFailed The status is not StatusReady
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore
ErrorConflict There was a conflict with a concurrent operation from another device/user, try again

Sharing

Sharing a resource can be done during encryption, using the encryption options.

GetResourceID

Retrieves an encrypted resource's ID.

func (t *Tanker) GetResourceId(encryptedData []byte) (*string, error)

The resource ID can then be used to call share.

Note

This function does not have any requirement on Tanker's status.

Parameters
encryptedData: []byte The encrypted resource from which you want the ID
Returns
string The ID of the given encrypted resource
Errors Description
ErrorInvalidArgument The argument is an invalid resource

Share

Shares resources with users and groups.

func (t *Tanker) Share(resourceIDs []string, recipients []string, groups []string) error

This function either fully succeeds or fails. In this case, it does not share with any recipient.

Parameters
resourceIds: []string Resource IDs to share
recipients: []string User public identities to share with
groups: []string Group IDs to share with
Errors Description
ErrorPreconditionFailed The status is not StatusReady
ErrorInvalidArgument Some recipients (groups or users) have not been found
ErrorInvalidArgument Some resource IDs have not been found
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

Pre-registration sharing

AttachProvisionalIdentity

Attaches a provisional identity to the user.

func (t *Tanker) AttachProvisionalIdentity(provisionalIdentity string) (*AttachResult, error)

Depending on the result, verifying the provisional identity with VerifyProvisionalIdentity might be necessary.

Parameters
provisionalIdentity: string A provisional identity
Returns
*AttachResult An AttachResult
Errors Description
ErrorInvalidArgument The provided provisional identity is invalid
ErrorPreconditionFailed The status is not StatusReady
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

AttachResult

The AttachProvisionalIdentity function returns a type with the following properties:

Member Description
Status Status The provisional identity's status. Either StatusReady or StatusIdentityVerificationNeeded
Method *VerificationMethod A verification method containing the email matching the created provisional identity

VerifyProvisionalIdentity

Verifies an attached provisional identity.

func (t *Tanker) VerifyProvisionalIdentity(verification interface{}) error

Once the provisional identity is verified, every resource shared with it can now be decrypted by the user, who also joins every group in which the provisional identity was a member.

Parameters
verification: Verification A verification containing the provisional identity's email, and the verification code
Errors
ErrorPreconditionFailed The status of the current session is not StatusReady
ErrorPreconditionFailed The status of the attach result is not StatusIdentityVerificationNeeded
ErrorExpiredVerification The verification expired
ErrorInvalidVerification The verification is invalid
ErrorTooManyAttempts Too many verification attempts occurred. Please retry later.
ErrorDeviceRevoked The current device is already revoked and cannot be used anymore

Events

Warning

Not implemented yet for Go.

RegisterEventHandler

RegisterEventHandler registers an EventHandler for the given EventType.

func (t *Tanker) RegisterEventHandler(event EventType, handler EventHandler) error
Parameters
event: EventType The type of event one can register and be notified of
handler: EventHandler EventHandler defines the function object type used by RegisterEventHandler().

EventType

EventType represents the type of event one can register and be notified of.

DeviceRevoked

Emitted when the current device has been revoked. The revocation can be initiated on any device the user has registered, including the current device.

RegisterEventHandler(EventDeviceRevoked, handler);

Utilities

PrehashPassword

func PrehashPassword(password string) (string, error)

Utility function to hash a password client side. This function is only useful in the specific case described in the verification by passphrase guide.