encryptOtpCodeToBundle function
Encrypts an OTP code and a client public key to the target encryption key provided by the enclave during initOtp. The resulting encrypted bundle is sent to verifyOtpV2 so the enclave can decrypt it, verify the OTP code, and issue a verification token bound to the client's public key.
Verifies the enclave signature on the target bundle before encrypting.
Parameters:
otpCode: The OTP code entered by the user.otpEncryptionTargetBundle: The signed target encryption bundle returned from initOtp.publicKey: Compressed hex public key to embed in the encrypted bundle.dangerouslyOverrideSignerPublicKey: Optional override for the TLS fetcher signing key used to verify the bundle signature. Only use in test/preprod environments.
Returns:
- A Future<String> resolving to the encrypted OTP bundle string.
Throws:
- Exception: If bundle signature verification or encryption fails.
Implementation
Future<String> encryptOtpCodeToBundle({
required String otpCode,
required String otpEncryptionTargetBundle,
required String publicKey,
String? dangerouslyOverrideSignerPublicKey,
}) async {
final Map<String, dynamic> parsedBundle =
jsonDecode(otpEncryptionTargetBundle);
final bool verified = verifyEnclaveSignature(
enclaveQuorumPublic: parsedBundle['enclaveQuorumPublic'],
publicSignature: parsedBundle['dataSignature'],
signedData: parsedBundle['data'],
dangerouslyOverrideSignerPublicKey: dangerouslyOverrideSignerPublicKey ??
PRODUCTION_TLS_FETCHER_SIGN_PUBLIC_KEY,
);
if (!verified) {
throw Exception(
'OTP encryption target bundle signature verification failed');
}
final Map<String, dynamic> signedData = jsonDecode(
utf8.decode(uint8ArrayFromHexString(parsedBundle['data'])),
);
if (signedData['targetPublic'] == null) {
throw Exception('Missing "targetPublic" in bundle signed data');
}
final Uint8List targetKeyBuf =
uint8ArrayFromHexString(signedData['targetPublic']);
final Uint8List plainTextBuf = Uint8List.fromList(
utf8.encode(jsonEncode({'otp_code': otpCode, 'public_key': publicKey})),
);
final Uint8List encryptedBuf = hpkeEncrypt(
plainTextBuf: plainTextBuf,
targetKeyBuf: targetKeyBuf,
hpkeInfo: zeroxkeyHpkeInfo,
);
return formatHpkeBuf(encryptedBuf);
}