mte_core_login
- CSharp
- Java
- Swift
- Python
- Go
/// <summary>
/// Login to the server.
/// </summary>
/// <param name="clientId">The clientId.</param>
/// <param name="encoderState">The current encoderState.</param>
/// <param name="decoderState">The current decoderState.</param>
public ResponseModel<LoginResposne> LoginToServer(string clientId,
string encoderState,
string decoderState)
{
ResponseModel<LoginResposne> response = new ResponseModel<LoginResposne>
{ Data = new LoginResposne
{ EncoderState = encoderState, DecoderState = decoderState }
};
try
{
//-----------------------------------
// Login first before uploading file
// Use regular MTE
//-----------------------------------
string loginRoute = "api/login";
LoginModel login = new LoginModel
{ Password = "P@ssw0rd!", UserName = "email@eclypses.com" };
//---------------------------------
// Serialize login model and encode
//---------------------------------
string serializedLogin = JsonSerializer.Serialize(login);
//----------------------------------
// Encode outgoing message with MTE
//----------------------------------
MteEnc enc = new MteEnc();
MteStatus encoderStatus = enc.RestoreStateB64(encoderState);
if (encoderStatus != MteStatus.mte_status_success)
{
response.Message = $"Failed to restore MTE Encoder engine. Status: "
+ "{enc.GetStatusName(encoderStatus)} / "
+ "{enc.GetStatusDescription(encoderStatus)}";
response.Success = false;
response.ExceptionUid = Guid.NewGuid().ToString();
response.ResultCode = Constants.RC_MTE_STATE_RETRIEVAL;
return response;
}
string encodeResult = enc.EncodeB64(serializedLogin);
//---------------------------
// Save updated Encoder State
//---------------------------
response.Data.EncoderState = enc.SaveStateB64();
//-------------------
// Perform Login
//-------------------
string loginResponse =
MakeHttpCall($"{Constants.RestAPIName}/api/login", HttpMethod.Post, clientId,
Constants.TextContentType, encodeResult).Result;
//---------------------------------------
// Deserialize the result from login
//---------------------------------------
ResponseModel<string> serverResponse =
JsonSerializer.Deserialize<ResponseModel<string>>
(loginResponse, Constants.JsonOptions);
//--------------
// If error end
//--------------
if (!serverResponse.Success)
{
response.Message = serverResponse.Message;
response.Success = serverResponse.Success;
response.ExceptionUid = serverResponse.ExceptionUid;
response.ResultCode = serverResponse.ResultCode;
return response;
}
//----------------------
// Set jwt/access_token
//----------------------
response.access_token = serverResponse.access_token;
//---------------------------------------------
// Decode the response and resave Decoder State
//---------------------------------------------
MteDec dec = new MteDec();
MteStatus decoderStatus = dec.RestoreStateB64(decoderState);
if (decoderStatus != MteStatus.mte_status_success)
{
response.Message = $"Failed to restore MTE Decoder engine. Status: "
+ "{dec.GetStatusName(decoderStatus)} / "
+ "{dec.GetStatusDescription(decoderStatus)}";
response.Success = false;
response.ExceptionUid = Guid.NewGuid().ToString();
response.ResultCode = Constants.RC_MTE_STATE_RETRIEVAL;
return response;
}
var decodedResult = dec.DecodeStrB64(serverResponse.Data);
Console.WriteLine($"Login response: {decodedResult}");
response.Data.DecoderState = dec.SaveStateB64();
response.Data.LoginMessage = decodedResult;
}
catch (Exception ex)
{
response.Message = $"Exception during login: {ex.Message}";
response.Success = false;
response.ExceptionUid = Guid.NewGuid().ToString();
response.ResultCode = Constants.RC_LOGIN_EXCEPTION;
}
return response;
}
/**
* Login using MTE Core
* @param clientId -- conversation/client Id
* @param handshake - Encoder and Decoder states
* @return
*/
private static ResponseModel<LoginResponse> LoginToServer(String clientId,
HandshakeResponse handshake) {
ResponseModel<LoginResponse> response = new ResponseModel<LoginResponse>();
response.Data = new LoginResponse(handshake.EncoderState, handshake.DecoderState);
try {
//---------------------------------------------------
// Set login -- demo only this should be more secure
//---------------------------------------------------
LoginModel login = new LoginModel("email@eclypses.com","P@ssw0rd!");
//-----------------------------------
// Serialize and Encode with Core MTE
//-----------------------------------
String serializedLogin = _gson.toJson(login);
MteEnc mteEnc = new MteEnc();
MteStatus encoderStatus = mteEnc.restoreStateB64(handshake.EncoderState);
if(encoderStatus != MteStatus.mte_status_success) {
//--------------------------------
// Return error if not successful
//--------------------------------
response.Message = "Failed to restore MTE Encoder engine. Status: " +
MteBase.getStatusName(encoderStatus) + " / " +
MteBase.getStatusDescription(encoderStatus);
response.Success = false;
response.ResultCode = Constants.RC_MTE_STATE_RETRIEVAL;
response.ExceptionUid = UUID.randomUUID().toString();
return response;
}
//--------------------------------------------
// Encode Login with MTE Core and Save State
//--------------------------------------------
StrStatus encodedLogin = mteEnc.encodeB64(serializedLogin);
if(encodedLogin.status != MteStatus.mte_status_success) {
//--------------------------------
// Return error if not successful
//--------------------------------
response.Message = "Failed to encode login. Status: " +
MteBase.getStatusName(encodedLogin.status) + " / " +
MteBase.getStatusDescription(encodedLogin.status);
response.Success = false;
response.ResultCode = Constants.RC_MTE_ENCODE_EXCEPTION;
response.ExceptionUid = UUID.randomUUID().toString();
return response;
}
response.Data.EncoderState = mteEnc.saveStateB64();
//----------------------------
// Make login call to server
//----------------------------
String serverResponse = MakeHttpCall(Constants.RestAPIName + Constants.LoginRoute,
"POST",
clientId,Constants.TextContentType,
encodedLogin.str);
//---------------------------------------
// Deserialize the result from login
//---------------------------------------
Type loginResponseType = new TypeToken<ResponseModel<String>>() {
}.getType();
ResponseModel<String> loginResponse =
_gson.fromJson(serverResponse, loginResponseType);
//------------------------------
// If unsuccessful return error
//------------------------------
if(!loginResponse.Success) {
return loginResponse.ReturnDataWithResponseModel(loginResponse, response.Data);
}
//-----------------------------
// Set return JWT/access_token
//-----------------------------
response.access_token = loginResponse.access_token;
//----------------------------------------------
// Restore State to MTE Core
//----------------------------------------------
MteDec mteDec = new MteDec();
MteStatus decoderStatus = mteDec.restoreStateB64(handshake.DecoderState);
if(decoderStatus != MteStatus.mte_status_success) {
response.Message = "Failed to restore MTE Decoder engine. Status: " +
mteDec.getStatusName(decoderStatus) + " / " +
mteDec.getStatusDescription(decoderStatus);
response.Success = false;
response.ResultCode = Constants.RC_MTE_STATE_RETRIEVAL;
response.ExceptionUid = UUID.randomUUID().toString();
return response;
}
//---------------------------------------
// Decode message and Save Decoder State
//---------------------------------------
StrStatus decodedMessage = mteDec.decodeStrB64(loginResponse.Data);
if(decodedMessage.status != MteStatus.mte_status_success) {
response.Message = "Failed to decode login message. Status: " +
MteBase.getStatusName(decodedMessage.status) + " / " +
MteBase.getStatusDescription(decodedMessage.status);
response.Success = false;
response.ResultCode = Constants.RC_MTE_DECODE_EXCEPTION;
response.ExceptionUid = UUID.randomUUID().toString();
return response;
}
response.Data.DecoderState = mteDec.saveStateB64();
//-------------------------------
// Output login response message
//-------------------------------
System.out.println("Login response: " + decodedMessage.str);
response.Data.LoginMessage = decodedMessage.str;
}catch (Exception ex) {
ex.printStackTrace();
response.Message = "Exception during login: " + ex.getMessage();
response.Success = false;
response.ResultCode = Constants.RC_LOGIN_EXCEPTION;
return response;
}
return response;
}
import Foundation
let _jsonEncoder = getJSONEncoder()
let _jsonDecoder = getJSONDecoder()
print("****** Simple MTE Switching Console Demo ******\n")
enum PairType: String {
case encoder = "Enc"
case decoder = "Dec"
}
extension Data {
var bytes : [UInt8]{
return [UInt8](self)
}
}
extension String: LocalizedError {
public var errorDescription: String? { return self }
}
let main = Main()
RunLoop.current.run()
class Main: StreamUploadDelegate, MteEntropyCallback, MteNonceCallback, MteTimestampCallback {
var mteHelper: MTEHelper!
var fileStreamUpload: FileStreamUpload!
var pairType: PairType!
var tempEntropy = [UInt8]()
init() {
Settings.clientId = UUID().uuidString.lowercased()
// Instantiate FileStreamUpload class
fileStreamUpload = FileStreamUpload()
fileStreamUpload.streamUploadDelegate = self
// Instantiate the MTEHelper class
do {
mteHelper = try MTEHelper()
mteHelper.mteEntropyCallback = self
mteHelper.mteNonceCallback = self
} catch {
print("Unable to Instantiate MteHelper. Error: \(error.localizedDescription)")
exit(EXIT_FAILURE)
}
pairWithServer()
encodeAndSend(plaintext: "These are our [login credentials] that we need to keep secret!")
}
func pairWithServer() {
do {
try instantiateEncoder()
try instantiateDecoder()
} catch {
print(error.localizedDescription)
exit(EXIT_FAILURE)
}
}
fileprivate func instantiateEncoder() throws {
pairType = .encoder
mteHelper.encoderPersonalizationString = UUID().uuidString.lowercased()
try mteHelper.createEncoder()
print("Successfully Instantiated Encoder with Elliptic-Curve Diffie-Hellman Handshake\n")
}
fileprivate func instantiateDecoder() throws {
pairType = .decoder
mteHelper.decoderPersonalizationString = UUID().uuidString.lowercased()
try mteHelper.createDecoder()
print("Successfully Instantiated Decoder with Elliptic-Curve Diffie-Hellman Handshake\n")
}
func encodeAndSend(plaintext: String) {
var encodedData: Data!
if plaintext != "" {
do {
// encode to a string
let encodedPayloadStr = try mteHelper.encode(message: plaintext)
// and convert back to Data
encodedData = Data(encodedPayloadStr.utf8)
} catch {
print("Unable to encode Data. Error: \(error.localizedDescription)")
}
let connectionModel = ConnectionModel(url: Settings.serverUrl,
method: Constants.POST,
route: "api/mte/send-data",
payload: encodedData,
contentType: "text/plain; charset=utf-8",
clientId: Settings.clientId,
mteVersion: MteBase.getVersion())
WebService.call(connectionModel: connectionModel, onCompletion: { callResult in
switch callResult {
case .failure(let code, let message):
print("Communication with Server failed. ErrorCode: \(code). ErrorMessage: \(message)")
case .success(let data):
do {
// In this example, first, we'll convert the response data to a String
let dataStr = String(decoding: data, as: UTF8.self)
// then decode it
let decodedStr = try self.mteHelper.decode(encoded: dataStr)
print("Response from Server: \n\(decodedStr)")
// Call to upload a file when call to 'login' has completed.
// Uncomment for full Sample
// self.uploadStream("MobyDickeBook.txt")
} catch {
print("Unable to decode Data from Server. Error: \(error.localizedDescription)")
}
}
})
}
}
//MARK: Callbacks
func entropyCallback(_ minEntropy: Int,
_ minLength: Int,
_ maxLength: UInt64,
_ entropyInput: inout [UInt8],
_ eiBytes: inout UInt64,
_ entropyLong: inout UnsafeMutableRawPointer?) -> mte_status {
var myEntropyRaw: UnsafeMutableRawPointer? = nil
// We have a network call to get entropy so we have to block this thread until it returns.
// There is likely a better solution.
let semaphore = DispatchSemaphore(value: 0)
// entropyCallback function does not support concurrency so
// we will call the server in a Task to exchange ECDH public keys
Task.init {
try await getEntropy()
semaphore.signal()
}
let timeoutResult = semaphore.wait(timeout: .now() + 15)
if timeoutResult == .timedOut {
print("Timeout in getEntropy call for \(pairType.rawValue)")
}
if tempEntropy.count < minLength {
print("mte_status_drbg_catastrophic")
}
// Set the actual entropy length. It cannot exceed the maximum required.
let buffBytes = eiBytes
eiBytes = min(UInt64(tempEntropy.count), maxLength)
// If the length is greater than the length of the provided buffer, we have
// to create our own buffer instead.
if eiBytes > buffBytes {
// Get the entropy input as an array.
let ei = tempEntropy
// If there is previous raw entropy, deallocate it.
if myEntropyRaw != nil {
myEntropyRaw!.deallocate()
}
// Allocate unsafe memory for the entropy.
myEntropyRaw =
UnsafeMutableRawPointer.allocate(byteCount: ei.count, alignment: 16)
// Copy from the entropy array to the unsafe memory.
ei.withUnsafeBytes { buff in
let raw = myEntropyRaw!.assumingMemoryBound(to: UInt8.self)
let ei = buff.bindMemory(to: UInt8.self)
raw.assign(from: ei.baseAddress!, count: ei.count)
}
// Set the raw pointer to point at the unsafe memory.
entropyLong = myEntropyRaw
}
else {
// Copy the entropy to the buffer.
entropyInput.replaceSubrange(Range(uncheckedBounds: (0, Int(eiBytes))),
with: tempEntropy.prefix(Int(eiBytes)))
tempEntropy.resetBytes(in: 0..<tempEntropy.count)
}
// Success.
return mte_status_success
}
private func getEntropy() async throws {
var personalizationString: String!
switch pairType {
case .decoder:
personalizationString = mteHelper.decoderPersonalizationString
default:
personalizationString = mteHelper.encoderPersonalizationString
}
let ecdh = try EcdhHelper(name: "\(pairType.rawValue) Entropy")
let publicKey = try ecdh.getPublicKey()
// Send the public keys and IDs to the Server
let request = PairRequest(personalizationString: personalizationString,
publicKey: publicKey,
pairType: pairType.rawValue)
let payload = try _jsonEncoder.encode(request)
let connectionModel = ConnectionModel(url: Settings.serverUrl,
method: Constants.POST,
route: "api/pairone",
payload: payload,
contentType: "application/json; charset=utf-8",
clientId: Settings.clientId,
mteVersion: MteBase.getVersion())
let result = await WebService.call(connectionModel: connectionModel)
switch result {
case .failure(let code, let message):
print("Could not pair with Server. ErrorCode: \(code), ErrorMessage: \(message).")
exit(EXIT_FAILURE)
case .success(let data):
let response = try _jsonDecoder.decode(PairResponse.self, from: data)
try ecdh.createSharedSecret(remotePublicKeyStr: response.publicKey,
entropy: &tempEntropy)
switch self.pairType {
case .decoder:
self.mteHelper.decoderNonce = UInt64(response.timestamp)!
default:
self.mteHelper.encoderNonce = UInt64(response.timestamp)!
}
}
}
func nonceCallback(_ minLength: Int, _ maxLength: Int, _ nonce: inout [UInt8], _ nBytes: inout Int) {
var nCopied: Int = 0
switch pairType {
case .decoder:
// Copy the nonce in little-endian format to the nonce buffer.
nCopied = min(nonce.count, MemoryLayout.size(ofValue: mteHelper.decoderNonce))
for i in 0..<nCopied {
nonce[i] = UInt8(UInt64(mteHelper.decoderNonce >> (i * 8)) & 0xFF)
}
mteHelper.decoderNonce = 0
default:
// Copy the nonce in little-endian format to the nonce buffer.
nCopied = min(nonce.count, MemoryLayout.size(ofValue: mteHelper.encoderNonce))
for i in 0..<nCopied {
nonce[i] = UInt8(UInt64(mteHelper.encoderNonce >> (i * 8)) & 0xFF)
}
mteHelper.encoderNonce = 0
}
// If the minimum length is greater than the size of the nonce we got, fill
// up to that length with zeros.
if nCopied < minLength {
for i in nCopied..<minLength {
nonce[i] = 0
}
nBytes = minLength
}
else {
nBytes = nCopied
}
}
func timestampCallback() -> UInt64 {
// return the timestamp in milliseconds
return UInt64(Date().timeIntervalSince1970 * 1000.0)
}
}
MteHelper.swift
import Foundation
enum EncoderType {
case mte
case mke
case flen
}
enum DecoderType {
case mte
case mke
// No flen Decoder type necessary
}
// MTE Defaults
let defEncType = EncoderType.mte
let defDecType = DecoderType.mte
let defFixLen = 100
class MTEHelper {
var mteEntropyCallback: MteEntropyCallback!
var mteNonceCallback: MteNonceCallback!
// Set up some class variables we will be needing
private var encoderState: [UInt8]!
private var decoderState: [UInt8]!
var encoderEntropy = [UInt8](repeating: 0, count: 32)
var encoderNonce: UInt64 = 0
var encoderPersonalizationString: String!
var decoderEntropy = [UInt8](repeating: 0, count: 32)
var decoderNonce: UInt64 = 0
var decoderPersonalizationString: String!
// Encoders
private var mteEncoder: MteEnc!
private var mkeEncoder: MteMkeEnc!
private var flenEncoder: MteFlenEnc!
// Decoders
private var mteDecoder: MteDec!
private var mkeDecoder: MteMkeDec!
// no flen decoder is necessary
// MARK: init
init() throws {
// Get version of MTE we are using
let mteVersion: String = MteBase.getVersion()
print("Using MTE Version \(mteVersion)\n")
// Check mte license
if !MteBase.initLicense(Settings.licCompanyName, Settings.licCompanyKey) {
throw "License Check failed."
}
}
// MARK: CreateEncoder
func createEncoder() throws {
let encoder = try MteEnc()
try instantiateEncoder(encoder: encoder)
}
func createEncoder(drbg: mte_drbgs,
tokBytes: Int,
verifiers: mte_verifiers) throws {
let encoder = try MteEnc(drbg,
tokBytes,
verifiers)
try instantiateEncoder(encoder: encoder)
}
private func instantiateEncoder(encoder: MteEnc) throws {
var status = mte_status_success
encoder.setEntropyCallback(mteEntropyCallback)
encoder.setNonceCallback(mteNonceCallback)
// Instantiate MTE encoder
status = encoder.instantiate(encoderPersonalizationString)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
// print("EncoderState: \(encoder.saveStateB64()!)") // Uncomment to confirm encoder state value and
// and compare with Server decoder state. This is a particularly useful debugging tool.
encoderState = encoder.saveState()
status = encoder.uninstantiate()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
}
// MARK: CreateDecoder
func createDecoder() throws {
let decoder = try MteDec()
try instantiateDecoder(decoder: decoder)
}
func createDecoder(timestampWindow: UInt64,
sequenceWindow: Int) throws {
let decoder = try MteDec(timestampWindow, sequenceWindow)
try instantiateDecoder(decoder: decoder)
}
func createDecoder(drbg: mte_drbgs,
tokBytes: Int,
verifiers: mte_verifiers,
timestampWindow: UInt64,
sequenceWindow: Int) throws {
let decoder = try MteDec(drbg,
tokBytes,
verifiers,
timestampWindow,
sequenceWindow)
try instantiateDecoder(decoder: decoder)
}
private func instantiateDecoder(decoder: MteDec) throws {
var status = mte_status_success
decoder.setEntropyCallback(mteEntropyCallback)
decoder.setNonceCallback(mteNonceCallback)
// Instantiate MTE encoder
status = decoder.instantiate(decoderPersonalizationString)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
// print("DecoderState: \(decoder.saveStateB64()!)") // Uncomment to confirm decoder state value and
// and compare with Server encoder state. This is a particularly useful debugging tool.
decoderState = decoder.saveState()
status = decoder.uninstantiate()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
}
// MARK: Encode
func encode(encoderType: EncoderType = defEncType, message: String, fixedLength: Int = defFixLen) throws -> String {
var encodeResult: (encoded: String, status: mte_status)!
var status: mte_status!
switch encoderType {
case .mte:
let encoder = try MteEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encodeB64(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
case .mke:
let encoder = try MteMkeEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encodeB64(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
case .flen:
let encoder = try MteFlenEnc(fixedLength)
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encodeB64(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
}
if encodeResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return encodeResult.encoded
}
func encode(encoderType: EncoderType = defEncType, message: [UInt8]) throws -> [UInt8] {
var encodeResult: (encoded: ArraySlice<UInt8>, status: mte_status)!
var status: mte_status!
switch encoderType {
case .mte:
let encoder = try MteEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encode(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
case .mke:
let encoder = try MteMkeEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encode(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
case .flen:
let encoder = try MteMkeEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
encodeResult = encoder.encode(message)
encoderState = encoder.saveState()
status = encoder.uninstantiate()
}
if encodeResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return Array(encodeResult.encoded)
}
// MARK: Decode
func decode(decoderType: DecoderType = defDecType, encoded: String) throws -> String {
var decodeResult: (str: String, status: mte_status)!
var status: mte_status!
switch decoderType {
case .mte:
let decoder = try MteDec()
status = decoder.restoreState(decoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
decodeResult = decoder.decodeStrB64(encoded)
decoderState = decoder.saveState()
status = decoder.uninstantiate()
case .mke:
let decoder = try MteMkeDec()
status = decoder.restoreState(decoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
decodeResult = decoder.decodeStrB64(encoded)
decoderState = decoder.saveState()
status = decoder.uninstantiate()
}
if decodeResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return decodeResult.str
}
func decode(decoderType: DecoderType = defDecType, encoded: [UInt8]) throws -> [UInt8] {
var decodeResult: (decoded: ArraySlice<UInt8>, status: mte_status)!
var status: mte_status!
switch decoderType {
case .mte:
let decoder = try MteDec()
status = decoder.restoreState(decoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
decodeResult = decoder.decode(encoded)
decoderState = decoder.saveState()
status = decoder.uninstantiate()
case .mke:
let decoder = try MteMkeDec()
status = decoder.restoreState(decoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
decodeResult = decoder.decode(encoded)
decoderState = decoder.saveState()
status = decoder.uninstantiate()
}
if decodeResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return Array(decodeResult.decoded)
}
// MARK: Chunking
func startEncrypt() throws -> MteMkeEnc {
var status: mte_status!
let encoder = try MteMkeEnc()
status = encoder.restoreState(encoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
status = encoder.startEncrypt()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return encoder
}
func encryptChunk(encoder: MteMkeEnc, buffer: inout [UInt8]) throws {
let status = encoder.encryptChunk(&buffer)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
}
func finishEncrypt(encoder: MteMkeEnc) throws -> [UInt8] {
let encryptFinishResult = encoder.finishEncrypt()
if encryptFinishResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: encryptFinishResult.status))"
}
encoderState = encoder.saveState()
let status = encoder.uninstantiate()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return Array(encryptFinishResult.encoded)
}
func startDecrypt() throws -> MteMkeDec {
var status: mte_status!
let decoder = try MteMkeDec()
status = decoder.restoreState(decoderState)
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
status = decoder.startDecrypt()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return decoder
}
func decryptChunk(decoder: MteMkeDec, data: Data) throws -> [UInt8] {
let decodeResult = decoder.decryptChunk(data.bytes)
if decodeResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: decodeResult.status))"
}
return Array(decodeResult.data)
}
func finishDecrypt(decoder: MteMkeDec) throws -> [UInt8] {
let finishDecryptResult = decoder.finishDecrypt()
if finishDecryptResult.status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: finishDecryptResult.status))"
}
decoderState = decoder.saveState()
let status = decoder.uninstantiate()
if status != mte_status_success {
throw "\(#function) error: \(resolveErrorMessage(status: status))"
}
return Array(finishDecryptResult.data)
}
func restoreEncoderState(state: [UInt8]) {
encoderState = state
}
func restoreDecoderState(state: [UInt8]) {
decoderState = state
}
func getEncoderState(state: inout [UInt8]) {
state = encoderState
}
func getDecoderState(state: inout [UInt8]) {
state = decoderState
}
private func resolveErrorMessage(status: mte_status) -> String {
return "Status: \(MteBase.getStatusName(status)). Description: \(MteBase.getStatusDescription(status))"
}
}
def login_to_server(self, client_id: str, encoder_state: str, decoder_state:str) -> ResponseModel:
"""
Login to the server using MTE Core.
"""
response = ResponseModel()
response.data = LoginResponse()
response.data.encoder_state = encoder_state
response.data.decoder_state = decoder_state
# Login first before uploading file.
# Use regular MTE.
login_route = "/api/login"
login = LoginModel()
login.password = "P@ssw0rd!"
login.username = "email@eclypses.com"
# Serialize login model and encode.
serialize_login = json.dumps(login, default=vars)
# Encode outgoing message with MTE.
enc = MteEnc.fromdefault()
encoder_status = enc.restore_state_b64(encoder_state)
if encoder_status != MteStatus.mte_status_success:
response.message = "Failed to restore MTE Encoder engine. Status: {0}: {1}".format(enc.get_status_name(encoder_status), enc.get_status_description(encoder_status))
response.success = False
response.exception_uid = str(uuid.uuid4())
response.result_code = Constants().RC_MTE_STATE_RETRIEVAL
return response
encode_result, encoder_status = enc.encode_b64(serialize_login)
if encoder_status != MteStatus.mte_status_success:
response.message = "Failed to encode the login. Status: {0}: {1}".format(enc.get_status_name(encoder_status), enc.get_status_description(encoder_status))
response.success = False
response.exception_uid = str(uuid.uuid4())
response.result_code = Constants().RC_MTE_ENCODE_EXCEPTION
return response
# Save updated Encoder state.
response.data.encoder_state = enc.save_state_b64()
# Perform Login.
headers = {
"Content-Type": "text/plain",
"accept": "*/*",
"Content-Length": str(len(encode_result)),
Constants().CLIENT_ID_HEADER: client_id
}
login_url = os.path.join(Constants().REST_API_NAME + login_route)
login_response = requests.post(
url=login_url, data=encode_result, headers=headers)
# Deserialize the result from login.
server_response = login_response.json()
# If there is an error then end.
if server_response['Success'] == False:
response.message = server_response['Message']
response.success = server_response['Success']
response.exception_uid = server_response["ExceptionUid"]
response.result_code = server_response['ResultCode']
return response
# Set jwt/access_token
response.access_token = server_response['access_token']
# Decode the response and resave Decoder state.
dec = MteDec.fromdefault()
decoder_status = dec.restore_state_b64(decoder_state)
if decoder_status != MteStatus.mte_status_success:
response.message = "Failed to restore MTE Decoder engine. Status: {0}: {1}".format(dec.get_status_name(decoder_status), dec.get_status_description(decoder_status))
response.success = False
response.exception_uid = str(uuid.uuid4())
response.result_code = Constants().RC_MTE_STATE_RETRIEVAL
return response
decoded_result, decoder_status = dec.decode_str_b64(server_response['Data'])
if decoder_status != MteStatus.mte_status_success:
response.message = "Failed to decode message. Status: {0}: {1}".format(dec.get_status_name(decoder_status), dec.get_status_description(decoder_status))
response.success = False
response.exception_uid = str(uuid.uuid4())
response.result_code = Constants().RC_MTE_DECODE_EXCEPTION
return response
print ("Login response: {0}".format(decoded_result))
response.data.decoder_state = dec.save_state_b64()
response.data.login_message = decoded_result
return response
/**
* Login to API server
* Uses default username and password
* Uses MTE Core
*/
func LoginToServer(clientId string) (out int, err error) {
//-----------------
// Set login model
// This is a demonstration, username and password should not
// Be put in code as plain text
login := LoginModel{
Password: "P@ssw0rd!",
UserName: "email@eclypses.com",
}
//--------------------------
// Serialize the login model
serializedLogin, err := json.Marshal(login)
if err != nil {
fmt.Println(err.Error())
return
}
//---------------------
// Create the Encoder
encoder := mte.NewEncDef()
defer encoder.Destroy()
//------------------------
// Restore Encoder state
encoderStatus := encoder.RestoreStateB64(encoderState)
if encoderStatus != mte.Status_mte_status_success {
errorMessage := "Encoder restore error (" + mte.GetStatusName(encoderStatus)
+ ", " + mte.GetStatusDescription(encoderStatus) + ")"
fmt.Println(errorMessage)
return int(encoderStatus), errors.New(errorMessage)
}
//----------------------------------
// Encode the serialized Login Model
encodedLogin, encoderStatus := encoder.EncodeB64(serializedLogin)
if encoderStatus != mte.Status_mte_status_success {
errorMessage := "Encode error " + mte.GetStatusName(encoderStatus)
+ " , " + mte.GetStatusDescription(encoderStatus)
fmt.Println(errorMessage)
return
}
//----------------------------
// Save updated Encoder state
encoderState = encoder.SaveStateB64()
//-----------------
// Make Http call
loginResponse, retcode, err := MakeHttpCall(restAPIName+loginRoute,
"POST",
clientId,
textContent,
encodedLogin)
if err != nil {
fmt.Println(err.Error())
return retcode, err
}
//-----------------------------
// Marshal json back to class
hrBytes := []byte(loginResponse)
var serverResponse ResponseModel[string]
json.Unmarshal(hrBytes, &serverResponse)
if !serverResponse.Success {
fmt.Println("Error back from server: " + serverResponse.Message
+ " Code: " + strconv.Itoa(errorFromServer))
return errorFromServer, errors.New(serverResponse.Message)
}
//-----------------------------------------
// Set access_token for next communication
access_token = serverResponse.access_token
//---------------------
// Decode the response
decoder := mte.NewDecDef()
defer decoder.Destroy()
//---------------------------
// Restore the Decoder state
decoderStatus := decoder.RestoreStateB64(decoderState)
if mte.StatusIsError(decoderStatus) {
errorMessage := "Decoder restore error (" + mte.GetStatusName(decoderStatus)
+ ", " + mte.GetStatusDescription(decoderStatus) + ")"
fmt.Println(errorMessage)
return int(decoderStatus), errors.New(errorMessage)
}
//-----------------------
// Decode return message
decodedMessage, decoderStatus := decoder.DecodeStrB64(serverResponse.Data)
if mte.StatusIsError(decoderStatus) {
errorMessage := "Decode error " + mte.GetStatusName(decoderStatus)
+ " , " + mte.GetStatusDescription(decoderStatus)
fmt.Println(errorMessage)
return int(decoderStatus), errors.New(errorMessage)
}
fmt.Println("Login Response: " + decodedMessage)
decoderState = decoder.SaveStateB64()
return 0, nil
}