mke_decode_chunking
- C
- C++
- CSharp
- Java
- Swift
- Python
- Go
// Init the MTE.
if (!mte_init(NULL, NULL))
{
printf("There was an error attempting to initialize the MTE.\n");
return 1;
}
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
if (!mte_license_init("LicenseCompanyName", "LicenseKey"))
{
printf("There was an error attempting to initialize the MTE License.\n");
return 1;
}
// Check encrypt and decrypt chunk sizes.
size_t block_size = mte_base_ciphers_block_bytes(MTE_CIPHER_ENUM);
if (block_size > 1)
{
printf("The chunk size must be set to 1.");
return 1;
}
mte_status status;
// Set personalization string to demo for this sample.
const char* personal = "demo";
// Set nonce to the timestamp.
nonce = get_timestamp();
// Get minimum entropy amount of bytes.
size_t min_entropy_bytes = mte_base_drbgs_entropy_min_bytes(MTE_DRBG_ENUM);
if (min_entropy_bytes == 0)
{
min_entropy_bytes = 1;
}
entropy_size = min_entropy_bytes;
entropy_buff = malloc(min_entropy_bytes);
// Create byte array of random bytes to use as entropy.
int res = get_random(entropy_buff, entropy_size);
if (res != 0)
{
printf("There was an error attempting to create random entropy.\n");
return res;
}
// Create default MKE Decoder.
mte_mke_dec_init_info decoder_info = MTE_MKE_DEC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM, MTE_CIPHER_ENUM, MTE_HASH_ENUM, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
static MTE_HANDLE decoder;
decoder = malloc(mte_mke_dec_state_bytes(&decoder_info));
// Initiate the Decoder state.
status = mte_mke_dec_state_init(decoder, &decoder_info);
if (status != mte_status_success)
{
printf("Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return 1;
}
// Set the Decoder instantiation information.
mte_drbg_inst_info dec_inst_info = { &entropy_input_callback, NULL, &nonce_callback, NULL, personal, strlen(personal) };
status = mte_mke_dec_instantiate(decoder, &dec_inst_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
char decoded_file_name[256] = "decoded";
strcat(decoded_file_name, file_extension);
// Delete any existing decoded file.
res = remove(decoded_file_name);
if (res == 0)
{
printf("Previous file %s deleted.\n", decoded_file_name);
}
// Get the chunk state size requirement.
buff_bytes = mte_mke_dec_decrypt_state_bytes(decoder);
// Create buffer to hold MTE decryption.
unsigned char* dec_mke_buf;
dec_mke_buf = malloc(buff_bytes);
// Start decrypt chunking session.
status = mte_mke_dec_decrypt_start(decoder, dec_mke_buf);
if (status != mte_status_success)
{
fprintf(stderr, "Error starting decryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
// Re-open encoded file, for read mode "r" and binary "b".
encoded_file = fopen(encoded_file_name, "rb");
// Open the decoded file, for write mode "w" and binary "b".
FILE* decoded_file;
decoded_file = fopen(decoded_file_name, "wb");
// Create buffer to hold decrypt chunk size.
char* decrypt_chunk_buf;
decrypt_chunk_buf = malloc(decrypt_chunk_size);
// Create buffer to hold decoded data, to be the size of the decrypt chunk plus the block size.
char* decoded_data_buf;
decoded_data_buf = malloc(decrypt_chunk_size + block_size);
mte_dec_args decoding_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, ×tamp_callback, NULL);
while (!feof(encoded_file))
{
// Set decrypt chunk to zero.
memset(decrypt_chunk_buf, '\0', decrypt_chunk_size);
// Read a portion of the file of size decrypt_chunk_size to the decryption buffer.
size_t amount = fread(decrypt_chunk_buf, 1, decrypt_chunk_size, encoded_file);
// Check if the amount read is 0, the end of encoded file has been reached.
if (amount == 0)
{
continue;
}
// chunk size + block size new decoded buffer
// Decrypt the chunk buffer. Use the amount read from this pass.
// Contrary to encryption, decryption in place is not allowed. A separate input buffer
// and decrypted buffer will be needed.
MTE_SET_DEC_IO(decoding_args, decrypt_chunk_buf, amount, decoded_data_buf);
status = mte_mke_dec_decrypt_chunk(decoder, dec_mke_buf, &decoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error decrypting chunk: Status: %s/%s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return false;
}
// Not all decrypt chunk calls will have data returned.
// If there is any data, write that to the file.
if (decoding_args.bytes > 0)
{
// Write the chunk buffer to the decoded file.
fwrite(decoding_args.decoded, 1, decoding_args.bytes, decoded_file);
fflush(decoded_file);
}
}
// Finish MKE decryption.
MTE_SET_DEC_IO(decoding_args, NULL, 0, decrypt_chunk_buf);
status = mte_mke_dec_decrypt_finish(decoder, dec_mke_buf, &decoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error finishing decryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
if (decoding_args.bytes > 0)
{
// Write the result bytes from decrypt finish.
fwrite(decoding_args.decoded, 1, decoding_args.bytes, decoded_file);
fflush(decoded_file);
}
// Free the decrypt buffer.
free(decrypt_chunk_buf);
// Free the decoded data buffer.
free(decoded_data_buf);
// Close the decoded file.
fclose(decoded_file);
// Close the encoded file.
fclose(encoded_file);
printf("Successfully decoded file %s\n", decoded_file_name);
// Create default MKE decoder.
MteMkeDec decoder;
decoder.setEntropyCallback(&cbs);
decoder.setNonceCallback(&cbs);
decoder.setTimestampCallback(&cbs);
status = decoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
std::string decodedFileName = "decoded" + fileExtention;
// Open the decoded file stream for writing and binary.
std::ofstream decodedFile;
// Delete any existing decoded file.
if (std::remove(decodedFileName.c_str()) == 0)
{
std::cout << "Deleted existing file " << decodedFileName << std::endl;
}
decodedFile.open(decodedFileName, std::ofstream::out | std::ofstream::binary);
// Start decrypt chunking session.
status = decoder.startDecrypt();
if (status != mte_status_success)
{
std::cerr << "Error starting decryption: ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Re-open encoded file, for reading and binary.
std::ifstream encodedInputFile;
encodedInputFile.open(encodedFileName, std::ifstream::in | std::ifstream::binary);
// Go through until the end of the input file.
while (!encodedInputFile.eof())
{
// Create buffer to hold decrypt chunk size.
char decryptChunkBuf[decryptChunkSize];
// Read a portion of the encoded file of size decryptChunkSize to the decryption buffer.
encodedInputFile.read(decryptChunkBuf, decryptChunkSize);
// The amount read from the stream.
std::streamsize amountRead = encodedInputFile.gcount();
// Decrypt the chunk buffer.
size_t decryptedBytes = 0;
const void* decryptedChunk = decoder.decryptChunk(decryptChunkBuf, amountRead, decryptedBytes);
// If there are any bytes decrypted, write that to the decoded file.
if (decryptedBytes > 0)
{
// Write the chunk buffer to the decoded file.
decodedFile.write(static_cast<const char*>(decryptedChunk), decryptedBytes);
decodedFile.flush();
}
}
// Finish MKE decryption.
size_t decryptedBytes = 0;
const void* decryptedChunk = decoder.finishDecrypt(decryptedBytes, status);
// If there are any bytes decrypted, write that to the decoded file.
if (decryptedBytes > 0)
{
// Write the chunk buffer to the decoded file.
decodedFile.write(static_cast<const char*>(decryptedChunk), decryptedBytes);
decodedFile.flush();
}
// Close the encoded file.
encodedFile.close();
// Close the decoded file.
decodedFile.close();
std::cout << "Successfully decoded file " << decodedFileName << std::endl;
string encodedFileName = "encodedText";
string decodedFileName = "decodedText";
//-----------------------------------------
// Get fPath from prompt in encoded sample
//-----------------------------------------
encodedFileName = $"{encodedFileName}{Path.GetExtension(fPath)}";
decodedFileName = $"{decodedFileName}{Path.GetExtension(fPath)}";
//--------------------------------
// Create default MTE MKE Decoder
//--------------------------------
MteMkeDec mkeDecoder = new MteMkeDec();
//---------------------------------------------------------------------------
// Set identifier (must be same as encoder)
// These values should be treated like encryption keys
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
//---------------------------------------------------------------------------
string identifier = "demo";
//---------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//---------------------------------------------------------------
int entropyMinBytes = mkeDecoder.GetDrbgsEntropyMinBytes(mkeDecoder.GetDrbg());
string entropy = (entropyMinBytes > 0) ? new String('0', entropyMinBytes) : entropy;
//---------------------------------
// Set MKE values for the Decoder
//---------------------------------
mkeDecoder.SetEntropy(Encoding.UTF8.GetBytes(entropy));
mkeDecoder.SetNonce(0);
//------------------------
// Initialize the Decoder
//------------------------
decoderStatus = mkeDecoder.Instantiate(identifier);
if (decoderStatus != MteStatus.mte_status_success)
{
throw new ApplicationException($"Failed to initialize the MTE decoder engine. "
+ $"Status: {mkeDecoder.GetStatusName(encoderStatus)} / "
+ $"{mkeDecoder.GetStatusDescription(encoderStatus)}");
}
//-----------------------------
// Initialize chunking session
//-----------------------------
MteStatus decoderStatus = mkeDecoder.StartDecrypt();
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start decode chunk. Status: "
+ mkeDecoder.GetStatusName(decoderStatus)+ " / "
+ mkeDecoder.GetStatusDescription(decoderStatus));
}
//------------------------------------
// Read file in and decode using MKE
//------------------------------------
using (FileStream stream = File.OpenRead("encoded.txt"))
using (FileStream writeStream = File.OpenWrite("decoded.txt"))
{
BinaryReader reader = new BinaryReader(stream);
BinaryWriter writer = new BinaryWriter(writeStream);
//-----------------------------------
// Create a buffer to hold the bytes
//-----------------------------------
byte[] buffer = new Byte[1024];
int bytesRead;
//----------------------------------------
// While the read method returns bytes
// Keep writing them to the output stream
//----------------------------------------
while ((bytesRead = stream.Read(buffer, 0, 1024)) > 0)
{
//-------------------------------------------
// Ensure we are only decoding what was read
//-------------------------------------------
byte[] decodedData = new byte[0];
if (bytesRead == buffer.Length)
{
decodedData = _mkeDecoder.DecryptChunk(buffer);
}
else
{
//------------------------------------------
// Find out what the decoded length will be
//------------------------------------------
var cipherBlocks = _mkeDecoder.GetCiphersBlockBytes(_mkeDecoder.GetCipher());
int buffBytes = bytesRead - cipherBlocks;
//----------------------------------
// Allocate buffer for decoded data
//----------------------------------
decodedData = new byte[buffBytes];
int decryptError = _mkeDecoder.DecryptChunk(buffer, 0, bytesRead, decodedData, 0);
if (decryptError < 0)
{
throw new ApplicationException("Error decoding data.");
}
}
writeStream.Write(decodedData, 0, decodedData.Length);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
byte[] finalDecodedChunk = mkeDecoder.FinishDecrypt(out MteStatus finishStatus);
if(finishStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish decode chunk. Status: "
+ mkeDecoder.GetStatusName(finishStatus)+ " / "
+ mkeDecoder.GetStatusDescription(finishStatus));
}
//-----------------------------------------------------------------------
// Check if there is additional bytes if not initialize empty byte array
//-----------------------------------------------------------------------
if(finalDecodedChunk.Length <=0) { finalDecodedChunk = new byte[0]; }
//------------------------------------
// Append the final data to the file
//------------------------------------
writeStream.Write(finalDecodedChunk, 0, finalDecodedChunk.Length);
}
private static final int BUFFER_SIZE = 1024; // 1KB
private static String _pathToEncodedFile = "src/encoded";
private static String _pathToDecodedFile = "src/decoded";
private static final String _defaultExtension = ".txt";
//------------------------
// Create default Decoder
//------------------------
MteMkeDec mkeDecoder = new MteMkeDec();
//----------------------------------------------------------------------
// Set identifier
// These values should be treated like encryption keys
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
//----------------------------------------------------------------------
String identifier = "demo";
//----------------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//----------------------------------------------------------------------
int entropyMinBytes = MteBase.getDrbgsEntropyMinBytes(mkeDecoder.getDrbg());
String entropy = "0";
entropy = entropy.repeat(entropyMinBytes);
//--------------------------------
// Set MKE values for the Decoder
//--------------------------------
mkeDecoder.setEntropy(entropy.getBytes());
mkeDecoder.setNonce(0);
//------------------------
// Initialize MKE Decoder
//------------------------
MteStatus decoderStatus = mkeDecoder.instantiate(identifier);
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to initialize decoder. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
//-----------------------------
// Initialize chunking session
//-----------------------------
decoderStatus = mkeDecoder.startDecrypt();
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start decode chunk. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
//---------------------------------
// Clean up decoded file if exists
//---------------------------------
// Use decoded file created in encoded code
Path fileToDeletePathDC = Paths.get(_pathToDecodedFile);
Files.deleteIfExists(_pathToDecodedFile);
try (
//------------------------------------
// Read file in and decode using MKE
//------------------------------------
InputStream inputStream = new FileInputStream(outputFile);
OutputStream outputStream = new FileOutputStream(_pathToDecodedFile);
) {
byte[] buffer = new byte[BUFFER_SIZE];
int cipherBlock = mkeDecoder.getCiphersBlockBytes(mkeDecoder.getCipher());
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
//-------------------------------------------------------
// If bytesRead is equal to buffer do simple decodeChunk
//-------------------------------------------------------
byte[] decodedChunk = new byte[0];
if (bytesRead == buffer.length)
{
decodedChunk = _mkeDecoder.decryptChunk(buffer);
}
else
{
//------------------------------------------
// Find out what the decoded length will be
//------------------------------------------
int cipherBlock = _mkeDecoder.getCiphersBlockBytes(_mkeDecoder.getCipher());
int buffBytes = bytesRead - cipherBlock;
//----------------------------------
// Allocate buffer for decoded data
//----------------------------------
decodedChunk = new byte[buffBytes];
int decryptError = _mkeDecoder.decryptChunk(buffer, 0, bytesRead, decodedChunk, 0);
if (decryptError < 0)
{
throw new IllegalArgumentException("decrypt chunk error.");
}
}
//-----------------------------
// Write decoded chunk to file
//-----------------------------
outputStream.write(decodedChunk);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
MteBase.ArrStatus finalEncodedChunk = mkeDecoder.finishDecrypt();
if(finalEncodedChunk.status != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish decode chunk. Status: "
+ MteBase.getStatusName(finalEncodedChunk.status)+ " / "
+ MteBase.getStatusDescription(finalEncodedChunk.status));
}
//-----------------------------------------------------------------------
// Check if there is additional bytes if not initialize empty byte array
//-----------------------------------------------------------------------
if(finalEncodedChunk.arr.length <=0) { finalEncodedChunk.arr = new byte[0]; }
//-----------------------------------
// Append the final data to the file
//-----------------------------------
outputStream.write(finalEncodedChunk.arr);
} catch (IOException ex) {
ex.printStackTrace();
}
// Create default MKE decoder.
MteMkeDec decoder;
decoder.setEntropyCallback(&cbs);
decoder.setNonceCallback(&cbs);
decoder.setTimestampCallback(&cbs);
status = decoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
let decodedFileName = "decoded" + fileExtension
// Delete any existing decoded file.
if FileManager.default.fileExists(atPath: decodedFileName) {
try! FileManager.default.removeItem(atPath: decodedFileName)
print("File (\(decodedFileName) was deleted.")
}
// Open the decoded file for writing.
FileManager.default.createFile(atPath: decodedFileName, contents: nil)
let decodedFile: FileHandle
do {
decodedFile = try FileHandle(forWritingTo: URL.init(filePath: decodedFileName))
} catch {
print ("Error creating file \(decodedFileName)")
return -1
}
// Start decrypt chunking session.
status = decoder.startDecrypt()
if status != mte_status_success {
print("Error starting decryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Re-open encoded file.
let encodedInputFile: FileHandle
do {
encodedInputFile = try FileHandle(forReadingFrom: URL.init(filePath: encodedFileName))
} catch {
print ("Error creating file \(encodedFileName)")
return -1
}
// Go through until the end of the input file.
while (true) {
// Create buffer to hold decrypt chunk size.
let data = encodedInputFile.readData(ofLength: decryptChunkSize)
let decryptChunkBuf = data.bytes
// Read a portion of the encoded file of size decryptChunkSize to the decryption buffer.
if (data.count == 0) {
break
}
// Decrypt the chunk buffer.
let decryptedResult = decoder.decryptChunk(decryptChunkBuf)
status = decryptedResult.status
if status != mte_status_success {
print("Error decrypting chunk (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// If there are any bytes decrypted, write that to the decoded file.
if decryptedResult.data.count > 0 {
// Write the chunk buffer to the decoded file.
do {
try decodedFile.write(contentsOf: decryptedResult.data)
} catch {
print ("Error attempting to write to file " + decodedFileName)
return -1
}
}
}
// Finish MTE decryption.
let decryptedResult = decoder.finishDecrypt()
status = decryptedResult.status
if status != mte_status_success {
print("Error finishing decryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// If there are any bytes decrypted, write that to the decoded file.
if decryptedResult.data.count > 0 {
// Write the chunk buffer to the decoded file.
do {
try decodedFile.write(contentsOf: decryptedResult.data)
} catch {
print ("Error writing to \(decodedFileName)")
return -1
}
}
// Close the encoded fie.
do {
try encodedInputFile.close()
} catch {
print ("Error closing \(encodedFileName)")
}
// Close the decoded file.
do {
try decodedFile.close()
} catch {
print ("Error closing \(decodedFileName)")
}
print ("Successfully decoded file \(decodedFileName)")
#!/usr/bin/env python3
# Import relevant modules for the program.
from MteMkeDec import MteMkeDec
from MteStatus import MteStatus
from MteBase import MteBase
import os
import sys
def main():
# Create MKE Decoder.
mke_decoder = MteMkeDec.fromdefault()
# Set identifier (same as Encoder)
# These values should be treated like encryption keys.
# The following personalization string and nonce values are for
# demonstration only and should not be used in a production environment
personal_str = "demo"
# Check how long entropy we need, set default all 0's.
# This should be treated like encryption keys - this is just an example.
entropy = "0"
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(mke_decoder.get_drbg())
while len(entropy) < entropy_min_bytes:
entropy += "0"
entropy = bytearray(entropy,'utf-8')
# Set mte values for the Decoder.
mke_decoder.set_entropy(entropy)
mke_decoder.set_nonce(0)
# Instantiate the MKE Decoder.
decoder_status = mke_decoder.instantiate(personal_str)
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Initialize chunking session.
decoder_status = mke_decoder.start_decrypt()
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Failed to start decoding session ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Open input file and create output file.
# Deletes output file if it exists.
decoded_file = "src/decoded.txt"
in_file = "src/encoded.txt"
try:
if os.path.exists(decoded_file):
os.remove(decoded_file)
except:
print("Error while deleting file ", decoded_file)
finally:
decoded_file = open(decoded_file,"wb")
in_file = open(in_file,"rb")
# While bytes read from file exist,
# continue to write them to output file.
bytes_decrypted = bytearray()
chunk_size = 1024 # Set buffer size.
while True:
in_bytes = in_file.read(chunk_size)
# Decrypt the chunk.
decrypted_chunk = mke_decoder.decrypt_chunk(in_bytes)
if len(decrypted_chunk) > 0:
bytes_decrypted += decrypted_chunk
# Remove white space null bytes from strings.
decrypted_str = decrypted_chunk.decode()
decoded_file.write(bytearray(decrypted_str.encode()))
elif len(in_bytes) == 0:
break
# Finish the chunking session.
decrypted_chunk,decoder_status = mke_decoder.finish_decrypt()
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Failed to finish the decryption session.\n({0}): {1}".format(status,message),\
file=sys.stderr)
return decoder_status.value
# Check for additional bytes and append them.
while len(decrypted_chunk.decode()) > 0:
bytes_decrypted += decrypted_chunk
decrypted_str = decrypted_chunk.decode()
decoded_file.write(bytearray(decrypted_str.encode()))
# Close IO stream files.
decoded_file.close()
in_file.close()
# Success.
return 0
package main
import (
"bufio"
"fmt"
"goSocket/mte"
"io"
"os"
"path/filepath"
"strings"
)
//-----------------------
// Application constants
//-----------------------
const (
bufferSize = 1024
defaultExtension = ".txt"
nonce = 1
identifier = "mySecretIdentifier"
companyName = ""
companyLicense = ""
)
func main() {
//------------------------------------
// Prompting message for file to copy
//------------------------------------
fmt.Print("Please enter path to file\n")
reader := bufio.NewReader(os.Stdin)
fPath, _ := reader.ReadString('\n')
//---------------------------
// take off carriage return
//---------------------------
fPath = strings.Replace(fPath, "\n", "", -1)
fPath = strings.Replace(fPath, "\r", "", -1)
//--------------------------------
// Check to make sure file exists
//--------------------------------
_, err := os.Stat(fPath)
if err != nil {
fmt.Printf("Path does not exist! %s", err)
return
}
encodedFileName := "encodedFile"
decodedFileName := "decodedFile"
//-----------------------
// Get the file extension
//-----------------------
extension := defaultExtension
fExt := filepath.Ext(fPath)
if len(fExt) > 0 {
extension = fExt
}
encodedFileName = encodedFileName + extension
decodedFileName = decodedFileName + extension
//--------------------------------
// Create MKE Decoder
//--------------------------------
decoder := mte.NewMkeDecDef()
defer decoder.Destroy()
//----------------------------------------------------
// defer the exit so all other defer calls are called
//----------------------------------------------------
retcode := 0
defer func() { os.Exit(retcode) }()
//------------------------------------
// Check version and output to screen
//------------------------------------
mteVersion := mte.GetVersion()
fmt.Printf("Using Mte Version %s\n", mteVersion)
//--------------------------------
// Check license -- use constants
// If no license can be blank
//--------------------------------
if !mte.InitLicense(companyName, companyLicense) {
fmt.Println("There was an error attempting to initialize the MTE License.")
return
}
//----------------------------------------------------------------------------
// check how long entropy we need, set default
// Providing Entropy in this fashion is insecure. This is for demonstration
// purposes only and should never be done in practice.
//----------------------------------------------------------------------------
entropyBytes := mte.GetDrbgsEntropyMinBytes(encoder.GetDrbg())
entropy := make([]byte, entropyBytes)
//---------------
// Fill with 0's
//---------------
for i := 0; i < entropyBytes; i++ {
entropy[i] = '0'
}
//---------------------
// Initialize decoder
//---------------------
decoder.SetEntropy(entropy)
decoder.SetNonceInt(nonce)
status = decoder.InstantiateStr(identifier)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//---------------------------------------------------
// now read and decode file into new destination -->
//---------------------------------------------------
fRead, err := os.Open(encodedFileName)
if err != nil {
fmt.Printf("error opening %s: %s", encodedFileName, err)
return
}
defer fRead.Close()
//--------------------------------
// If the file is there delete it
//--------------------------------
_, err = os.Stat(decodedFileName)
if err == nil {
e := os.Remove(decodedFileName)
if e != nil {
fmt.Printf("Error trying to delete file %s", decodedFileName)
}
}
//-------------------------------------
// Initialize decrypt chunking session
//-------------------------------------
status = decoder.StartDecrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "MTE Decoder startDecrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//--------------------------------
// Create final destination file
//--------------------------------
finalDest, err := os.Create(decodedFileName)
if err != nil {
fmt.Printf("Error trying to create final destination file %s, err: %s", decodedFileName, err)
}
defer finalDest.Close()
//----------------------------------
// Create buffer to read bytes into
//----------------------------------
//------------------------------------------
// Iterate through encoded file and decode
//------------------------------------------
for {
//------------------------------
// Create buffer for file parts
//------------------------------
buf := make([]byte, bufferSize)
amountRead, err := fRead.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("Error trying to read file %s, err: %s", encodedFileName, err)
}
//-----------------------------------------------------------
// If we reached the end of the file finish chunking session
//-----------------------------------------------------------
if amountRead == 0 {
//-----------------------------------------------
// Reached the end of the file, break out of loop
//-----------------------------------------------
break
}
//----------------------------------------------------------
// If the amount that was read is less than the buffer size,
// take a slice of the original buffer
//---------------------------------------------------------
if amountRead < bufferSize {
buf = buf[:amountRead]
}
decoded := decoder.DecryptChunk(buf)
if decoded == nil {
fmt.Fprintf(os.Stderr, "Decode error.\n")
break
}
if _, err := finalDest.Write(decoded); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", decodedFileName, err)
}
}
finishDecodeChunk, status := decoder.FinishDecrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "MTE Decoder finishDecrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//---------------------------------------------------------
// if the return bytes are nil -- set to empty byte array
//---------------------------------------------------------
if finishDecodeChunk != nil {
if _, err := finalDest.Write(finishDecodeChunk); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", encodedFileName, err)
}
}
//---------------------------
// Print out success message
//---------------------------
fmt.Printf("Finished creating %s file\n", decodedFileName)
}