Participant SDK Interfaces

You are required to provide the CASPClosedUnbound’s Crypto Asset Security Platform (“CASP”) provides the advanced technology and the architecture to secure crypto asset transactions. ParticipantClosedA member of any of the quorum groups. SDK with storage and key management interfaces. This section contains information and code samples to help you develop those interfaces.

Storage Interface

The storage interface that needs to be provided is com.unboundtech.casp.desktop.signer.CaspStorage. This interface enables the CASPClosedUnbound’s Crypto Asset Security Platform (“CASP”) provides the advanced technology and the architecture to secure crypto asset transactions. ParticipantClosedA member of any of the quorum groups. SDK to have persistent data and to access it as needed.

Instantiate the interface with this code:

public interface CaspStorage {
  void storeData(String key, String value) throws StorageException;
  String loadData(String key) throws StorageException;
  List<String> listKeys() throws StorageException;
}

Key Manager Interface

The key manager interface needs these associated functions:

  • generateEncryptionKey

  • generateAuthenticationKey
  • signWithAuthenticationKey
  • decryptWithEncryptionKey
  • CaspStatus

Instantiate the interface with this code:

public interface CaspKeyManager {
  void generateEncryptionKey(KeyReadyListener keyReadyListener);
  void generateAuthenticationKey(KeyReadyListener keyReadyListener);
  void signWithAuthenticationKey(AuthenticationStrength authenticationStrength, byte[] data, String message, DataReadyListener
dataReadyListener);
  void decryptWithEncryptionKey(byte[] cypherText, DataReadyListener dataReadyListener);
  CaspStatus deleteKeys();
}

public interface KeyReadyListener {
  void done(final CaspStatus status, final String key);
}

public enum AuthenticationStrength {
  WEAK, STRONG, NONE
}

public interface DataReadyListener {
  void done(final CaspStatus status, final byte[] data);
}

The ParticipantClosedA member of any of the quorum groups. SDK uses the function generateEncryptionKey to generate the encryption key. This encryption key is used to decrypt data coming from the CASPClosedUnbound’s Crypto Asset Security Platform (“CASP”) provides the advanced technology and the architecture to secure crypto asset transactions. server.

The generateEncryptionKey function:

  1. Generates an RSA key-pair with a size of at least 2048-bits.
  2. Returns the public key in PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#8 DERClosedDistinguished Encoding Rules - it is a file containing a digital certificate in binary format, instead of the instead of the ASCII PEM format format, encoded in Base64.

For example:

@Override
public void generateEncryptionKey(KeyReadyListener keyReadyListener) {
  try {
    CertAndKeyGen certGen = new CertAndKeyGen(ENC_KEY_TYPE, ENCR_KEY_CERT_SIG);
    certGen.generate(ENC_KEY_SIZE);
    X509Certificate cert = certGen.getSelfCertificate(getX500Name(), FIVE_YEARS_IN_SECONDS);
    this.keyStore.setKeyEntry(ENC_KEY_ALIAS, certGen.getPrivateKey(), password.toCharArray(), new X509Certificate[]{cert});
    saveKeystoreToDisk();
    keyReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_SUCCESS), Base64Converter.toBase64(certGen.getPublicKey().getEncoded()));
  } catch (Exception e) {
    CaspLog.e(TAG, "failed to create encryption key", e);
    keyReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_EFAIL), null);
  }
}

The function generateAuthenticationKey generates the authentication key, which is used to authenticate the participantClosedA member of any of the quorum groups. to the CASPClosedUnbound’s Crypto Asset Security Platform (“CASP”) provides the advanced technology and the architecture to secure crypto asset transactions. service.

The generateAuthenticationKey function:

  1. Generates an EC key with a size of at least 256-bits.
  2. Returns the public key in PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#8 DERClosedDistinguished Encoding Rules - it is a file containing a digital certificate in binary format, instead of the instead of the ASCII PEM format format, encoded in Base64.

For example:

@Override
public void generateAuthenticationKey(KeyReadyListener keyReadyListener) {
  try {
    CertAndKeyGen certGen = new CertAndKeyGen(AUTH_KEY_TYPE, AUTH_KEY_CERT_SIG);
    certGen.generate(AUTH_KEY_SIZE);
    X509Certificate cert = null;
    cert = certGen.getSelfCertificate(getX500Name(), FIVE_YEARS_IN_SECONDS);
    this.keyStore.setKeyEntry(AUTH_KEY_ALIAS, certGen.getPrivateKey(), password.toCharArray(), new X509Certificate[]{cert});
    saveKeystoreToDisk();
    keyReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_SUCCESS), Base64Converter.toBase64(certGen.getPublicKey().getEncoded()));
  } catch (Exception e) {
    CaspLog.e(TAG, "failed to create authentication key", e);
    keyReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_EFAIL), null);
  }
}

Notes
- CertAndKeyGen is part of the JDK.
- bytesToBase64 is a method that gets a byte array as input and returns it encoded in base64 as string.

The signWithAuthenticationKey function does the following:

  1. Signs the provided data.
  2. Returns the signature in a PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#8 DERClosedDistinguished Encoding Rules - it is a file containing a digital certificate in binary format, instead of the instead of the ASCII PEM format format, encoded in Base64.

For example:

@Override
public void signWithAuthenticationKey(AuthenticationStrength authenticationStrength, byte[] dataToSign, String message, DataReadyListener dataReadyListener) {
  try {
    KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) this.keyStore.getEntry(AUTH_KEY_ALIAS, getKeyStorePP());
    if (entry == null) {
      CaspLog.e(TAG, "auth key is missing");
      throw new CryptoException("authentication key missing");
    }
    Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
    ecdsaSign.initSign(entry.getPrivateKey());
    ecdsaSign.update(dataToSign);
    dataReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_SUCCESS), ecdsaSign.sign());
  } catch (Exception e) {
    dataReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_EUSER_NOT_AUTHENTICATED), null);
    CaspLog.e(TAG, "failed to sign with auth key", e);
  }
}

The decryptWithEncryptionKey function decrypts the participantClosedA member of any of the quorum groups. data.

The function:

  1. Decrypts that data with the cipher:
    RSA/ECB/OAEPwithSHA-256andMGF1Padding
  2. Returns the plain text data.

For example:

@Override
public void decryptWithEncryptionKey(byte[] cypherText, DataReadyListener dataReadyListener) {
  try {
    KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(ENC_KEY_ALIAS, getKeyStorePP());
    if (entry == null) {
      CaspLog.e(TAG, "encryption key is missing");
      dataReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_EUSER_NOT_AUTHENTICATED), null);
      throw new CryptoException("encryption key missing");
    }
    byte[] clearText;
    try {
      Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding");
      cipher.init(Cipher.DECRYPT_MODE, entry.getPrivateKey());
      clearText = cipher.doFinal(cypherText);
    } catch (BadPaddingException e) {
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
      cipher.init(Cipher.DECRYPT_MODE, entry.getPrivateKey());
      clearText = cipher.doFinal(cypherText);
    }
    dataReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_SUCCESS), clearText);
  } catch (Exception e) {
    dataReadyListener.done(CaspStatus.constructByValue(CaspStatus.DY_EUSER_NOT_AUTHENTICATED), null);
    CaspLog.e(TAG, "failed to sign with enc key", e);
  }
}

REST Client

A RESTClosedRepresentational State Transfer (REST) - an architectural style that defines a set of constraints and properties based on HTTP. Web Services that conform to the REST architectural style, or RESTful web services, provide interoperability between computer systems on the Internet. client is provided as part of the SDK that can be used for production. The client assumes that you are using a direct connection (i.e. not a proxy).

The client can be instantiated as follows:

CaspRestClient restClient = new JavaRestClient(serverUrl, allowInsecureConnection, caspKeyManager, null);

Note that you need to have caspKeyManager already initialized for this call.

The parameter AuthenticationStrength should always be set to STRONG.

public interface CaspRestClient {
  void post(AuthenticationStrength authenticationStrength, String endpoint, String body, RestResponseListener listener);

  void put(AuthenticationStrength authenticationStrength, String endpoint, String body, RestResponseListener listener);

  void get(AuthenticationStrength authenticationStrength, String endpoint, RestResponseListener listener);

  void setResponseSignKey(String responseSignKey);

  interface RestResponseListener {
    void response(CaspStatus status, String body);
  }
}

Initialization

The CASPClosedUnbound’s Crypto Asset Security Platform (“CASP”) provides the advanced technology and the architecture to secure crypto asset transactions. ParticipantClosedA member of any of the quorum groups. SDK is initialized with the storage and key management interfaces.

CaspStatus initStatus = new CaspInitBuilder(caspStorage, caspKeyManager)
  restClient(restClient)
  init();

If you are using offline vaults, you can use this code to initialize:

CaspStatus initStatus = new CaspInitBuilder(caspStorage, caspKeyManager)
  init();