sign method

  1. @override
Future<String> sign({
  1. dynamic data,
  2. WalletStore? wallet,
  3. String? did,
  4. Map<String, dynamic>? jwk,
  5. bool detached = false,
  6. dynamic jwsHeader,
})
override

Build a (detached) JWS

Either using a combination of wallet and did or by using a private JsonWebKey jwk.

Implementation

@override
Future<String> sign(
    {dynamic data,
    WalletStore? wallet,
    String? did,
    Map<String, dynamic>? jwk,
    bool detached = false,
    dynamic jwsHeader}) async {
  String header;
  if (jwsHeader != null) {
    Map<String, dynamic>? headerMap;
    if (jwsHeader is String) {
      headerMap = jsonDecode(jwsHeader);
    } else {
      headerMap = jwsHeader;
    }
    if (headerMap!['alg'] != 'ES256K-R') {
      throw Exception('Unsupported signature algorithm ${headerMap['alg']}');
    }
    header = removePaddingFromBase64(
        base64UrlEncode(utf8.encode(jsonEncode(headerMap))));
  } else {
    var critical = <String, dynamic>{};
    critical['b64'] = false;
    header = removePaddingFromBase64(
        buildJwsHeader(alg: 'ES256K-R', extra: critical));
  }

  String signable = '';
  if (data is String) {
    signable = data;
  } else if (data is Map<String, dynamic>) {
    signable = jsonEncode(data);
  } else {
    throw Exception('Unexpected Datatype ${data.runtimeType} for toSign');
  }

  var payload =
      removePaddingFromBase64(base64UrlEncode(utf8.encode(signable)));
  var signingInput = '$header.$payload';
  var hash = sha256.convert(ascii.encode(signingInput)).bytes;
  String? privateKeyHex;

  if (did != null && wallet != null) {
    privateKeyHex = await wallet.getPrivateKeyForCredentialDid(did);
    privateKeyHex ??= await wallet.getPrivateKeyForConnectionDid(did);
    if (privateKeyHex == null) throw Exception('Could not find private key');
  } else if (jwk != null) {
    if (jwk['crv'] != 'secp256k1') {
      throw Exception('Wrong crv value for private key');
    }

    if (jwk['d'] == null) {
      throw Exception('This is no private key');
    }

    privateKeyHex = hexEncode(
        Uint8List.fromList(base64Decode(addPaddingToBase64(jwk['d']))));
  } else {
    throw Exception('No private key given. Can\'t sign data');
  }

  var key = EthPrivateKey.fromHex(privateKeyHex);
  var sigArray = _buildSignatureArray(hash as Uint8List, key);
  while (sigArray.length != 65) {
    sigArray = _buildSignatureArray(hash, key);
  }

  if (detached) {
    return '$header.'
        '.${removePaddingFromBase64(base64UrlEncode(sigArray))}';
  } else {
    return '$header.$payload'
        '.${removePaddingFromBase64(base64UrlEncode(sigArray))}';
  }
}