How to implement VERIFY command on NIST PIV cards? - c++

I must be doing something wrong, but I can't see what.
I'm trying to get the VERIFY command to show the number of attempts remaining. (I was trying to enter the PIN as well, but cut back to this when I couldn't get anything to work.) Here's the code fragment that I've been trying:
for (unsigned int basebyte = 0x00; basebyte != 0x100; basebyte += 0x80) {
for (unsigned char add = 0x01; add != 0x20; ++add) {
smartcard::bytevector_t b;
b.push_back(0x00); // CLA
b.push_back(0x20); // INS
b.push_back(0x00); // P1
b.push_back(basebyte + add); // P2 ("the sensible ranges are 0x01..0x1F and 0x81..0x9F")
//b.push_back(0x00); // Lc field -- length of the following data field
b = card.rawTransmit(b);
if (!card.status()) {
cout << "Received error '" << card.status() << "'" << endl;
} else {
if (b[0] == 0x6a && b[1] == 0x88) {
// "Referenced data not found"
continue;
}
cout << " Attempts remaining (" << std::hex << (basebyte + add) << std::dec << "): ";
cout << std::hex;
for (smartcard::bytevector_t::const_iterator i = b.begin(), ie = b.end();
i != ie; ++i) cout << std::setfill('0') << std::setw(2) << int(*i) << ' ';
cout << std::dec << endl;
}
}
}
The rawTransmit function...
bytevector_t rawTransmit(bytevector_t sendbuffer) {
SCARD_IO_REQUEST pioSendPci, pioRecvPci;
if (mProtocol.value() == SCARD_PROTOCOL_T0) {
pioSendPci = pioRecvPci = *SCARD_PCI_T0;
} else if (mProtocol.value() == SCARD_PROTOCOL_T1) {
pioSendPci = pioRecvPci = *SCARD_PCI_T1;
} else {
std::ostringstream out;
out << "unrecognized protocol '" << mProtocol.str() << "'";
throw std::runtime_error(out.str());
}
DWORD rlen = 256;
bytevector_t recvbuffer(rlen);
mResult = SCardTransmit(mHandle, &pioSendPci, &sendbuffer[0],
DWORD(sendbuffer.size()), &pioRecvPci, &recvbuffer[0], &rlen);
recvbuffer.resize(rlen);
return recvbuffer;
}
(bytevector_t is defined as std::vector<unsigned char>.)
All the cards using protocol T0 return 0x6a 0x88 ("Referenced data not found") for all P2 values. All the cards using T1 do the same, except when P2 is 0x81 -- then they say 0x69 0x84 ("Command not allowed, referenced data invalidated").
The cards in question definitely DO have PINs, and I can verify the PIN in the "Security Token Configurator" program provided by the middleware vendor, so I know that the card, reader, and middleware stuff are all working.
It's probably obvious, but I'm new to smartcard programming. Can anyone give me a clue where I'm going wrong?

The Global PIN has ID 00 and the PIV Card Application PIN has 80 (hex) so your tests do not include the known PIV card PIN ID's.

Related

inconsistent results while reading file in binary c++. READ BODY

As shown in the picture, if I read 2 bytes at offset 254786 and print it in hexadecimal, I should be getting 0xffd9 and I do get that exact value if I directly set the offset to 254786. however, if I set the offset to something far away from 254786 and run a while loop as shown in the second picture, I do not get 0xffd9. I really don't know where I could be possibly going wrong here.
std::ifstream myfile ("test-01.jpg");
if(!myfile) throw std::runtime_error("unable to open input file");
myfile.seekg(254786,myfile.beg);
std::string buf {};
buf.resize(2);
myfile.read(&buf[0], 2);
std::cout << std::hex << std::showbase << big_endian_2_bytes_to_int(buf);
0xffd9
int offset = 17000
std::cout << offset << std::endl;
myfile.seekg(offset,myfile.beg);
myfile.read(&buffer[0],2);
while ( big_endian_2_bytes_to_int(buffer) != 0xffd9){
offset++;
myfile.seekg(offset,myfile.beg);
myfile.read(&buffer[0],2);
if (offset == 254786){
std::cout << offset <<std::endl;
std::cout << std::hex << std::showbase << big_endian_2_bytes_to_int(buffer) << std::endl;
return 0;
}
}

How to use CRT batch technique in Microsoft SEAL 3.1?

Can you please tell me whether SEAL 3.1 supports PolyCRTBuilder class? I am trying to run the following program but failed because the class is not declared in this scope.
/**
Suppose I have two arrays x = [1,2,3,4,5] and xMean = [3,3,3,3,3]. I composed and encrypted the two array using PolyCRTBuilder ( xCiphertext and xMeanCiphertext ) . If I subtract the two ciphertexts ( xCiphertext MINUS xMeanCiphertext ), I should get xResult = [-2, -1, 0, 1, 2] but after the homomorphic subtraction I am getting xResultDecrypted = [40959, 40960, 0 ,1, 2] . I can relate the overflow result to the plain modulus set but is there a work around for this problem. Here is the code:
*/
#include <iostream>
#include "seal/seal.h"
using namespace std;
using namespace seal;
/*
Helper function: Prints the parameters in a SEALContext.
*/
void print_parameters(shared_ptr<SEALContext> context)
{
// Verify parameters
if (!context)
{
throw invalid_argument("context is not set");
}
auto &context_data = *context->context_data();
/*
Which scheme are we using?
*/
string scheme_name;
switch (context_data.parms().scheme())
{
case scheme_type::BFV:scheme_name = "BFV";
break;
case scheme_type::CKKS:scheme_name = "CKKS";
break;
default:
throw invalid_argument("unsupported scheme");
}
cout << "/ Encryption parameters:" << endl;
cout << "| scheme: " << scheme_name << endl;
cout << "| poly_modulus_degree: " << context_data.parms().poly_modulus_degree() << endl;
/*
Print the size of the true (product) coefficient modulus.
*/
cout << "| coeff_modulus size: " << context_data.
total_coeff_modulus_bit_count() << " bits" << endl;
/*
For the BFV scheme print the plain_modulus parameter.
*/
if (context_data.parms().scheme() == scheme_type::BFV)
{
cout << "| plain_modulus: " << context_data.
parms().plain_modulus().value() << endl;
}
cout << "\\ noise_standard_deviation: " << context_data.
parms().noise_standard_deviation() << endl;
cout << endl;
}
int main(){
cout << "\nTotal memory allocated from the current memory pool: "<< (MemoryManager::GetPool().alloc_byte_count() >> 20) << " MB" << endl;
EncryptionParameters parms(scheme_type::BFV);
//EncryptionParameters parms;
parms.set_poly_modulus_degree(4096);
parms.set_coeff_modulus(coeff_modulus_128(4096));
parms.set_plain_modulus(40961); ////Make the coefficient modulus prime>2n to enable CRT batching
auto context = SEALContext::Create(parms);
print_parameters(context);
IntegerEncoder encoder(parms.plain_modulus());
KeyGenerator keygen(context);
PublicKey public_key = keygen.public_key();
SecretKey secret_key = keygen.secret_key();
// SEALContext context(parms);
// KeyGenerator keygen(context);
// auto public_key = keygen.public_key();
// auto secret_key = keygen.secret_key();
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
PolyCRTBuilder crtbuilder(context);
int slot_count = crtbuilder.slot_count();
int row_size = slot_count / 2;
vector<uint64_t> x_pod_matrix(slot_count, 0);
x_pod_matrix[0] = 1;
x_pod_matrix[1] = 2;
x_pod_matrix[2] = 3;
x_pod_matrix[3] = 4;
x_pod_matrix[4] = 5;
Plaintext x_plain_matrix;
crtbuilder.compose(x_pod_matrix, x_plain_matrix);
Ciphertext x_encrypted_matrix;
encryptor.encrypt(x_plain_matrix, x_encrypted_matrix);
vector<uint64_t> x_mean_pod_matrix(slot_count, 0);
x_mean_pod_matrix[0] = 3;
x_mean_pod_matrix[1] = 3;
x_mean_pod_matrix[2] = 3;
x_mean_pod_matrix[3] = 3;
x_mean_pod_matrix[4] = 3;
Plaintext x_mean_plain_matrix;
crtbuilder.compose(x_mean_pod_matrix, x_mean_plain_matrix);
Ciphertext x_mean_encrypted_matrix;
encryptor.encrypt(x_mean_plain_matrix, x_mean_encrypted_matrix);
evaluator.sub_plain(x_encrypted_matrix, x_mean_encrypted_matrix);
// Decrypt x_encrypted_matrix
Plaintext x_plain_result;
decryptor.decrypt(x_encrypted_matrix, x_plain_result);
vector<uint64_t> pod_result;
crtbuilder.decompose(x_plain_result, pod_result);
for(int i = 0; i < 5; i++) {
std::cout << pod_result[i] << '\n';
}
return 0;
}
PolyCRTBuilder has been renamed to BatchEncoder. Take a look at the src/examples directory in SEAL v3.1 (or native/examples in a newer version) and you'll see plenty of examples.
Kind of related to your question: the coeff_modulus_128 function hasn't existed in SEAL for quite a while; the same functionality is provided by the CoeffModulus::BFVDefault function. With these changes your code might work in SEAL 3.5 even.

C++ Searching an array for a number but does not trigger else statement if it is not found

int gas;
// Input Code
int user_code;
std::cout << std::endl;
std::cout << "Please enter the Code: ";
std::cin >> user_code;
std::cout << "The value you entered is " << user_code;
std::cout << std::endl;
int array1[16] = { 42011, 42017, 42029, 42045,
42091, 42101, 34001, 34005,
34007, 34009, 34011, 34015,
34033, 10001, 10003, 24015 }; // 0.2387 (23.87%)
int array2[45] = { 11001, 24003, 24510, 24005, 24009,
24013, 24017, 24019, 24021, 24025,
24027, 24029, 24031, 24033, 24035,
24037, 24041, 24043, 51510, 51013,
51043, 51047, 51600, 51059, 51610,
51061, 51069, 51630, 51099, 51107,
51683, 51685, 51153, 51157, 51177,
51179, 51187, 51840, 54003, 54027,
54037, 54065, 42001, 42055, 42133 }; //0.2710 (27.10%)
int * array1_search;
array1_search = std::find(array1, array1+ 16, user_code);
int * array2_search;
array2_search = std::find(array2, array2 + 45, user_code);
if (array1_search != array1+ 16) {
std::cout << "Codefound in Array1: " << *array1_search << '\n';
gas= 0.2387;
}
else if (array2_search != array2_search + 45) {
std::cout << "Code found in Array2: " << *array2_search << '\n';
gas= 0.2710;
}
else {
std::cout << "Not found \n";
gas= 0.1506;
}
Above is my current code. I am trying to have the user input a variable user_code value and then iterate over the two arrays array1[16] and array2[45]. If the user input value is on the first array1 I want to assign gas 0.2387 and if the input value is on the other array2 I want to assign gas 0.2710, and if it is not within any array gas should be 0.1506.
So basically I want to assign a value depending on which array the user's input is contained in. I am very new to c++, what is the best way to go about this?
It seems to work fine if I enter a number that is within array1 or array2 and it correctly identifies that is found in array1 or array2. The problem is when I enter a number I know is not within either array to trigger the else statement it identifies it as being in array2. For example, when I enter 12345 as a user_code it says "Code found in Array2: 0". I know 12345 is not contained in array2 and I do not understand why *array2_search is assigned 0. What can I do to fix this so if a user_code is entered that is not contained within array1 or array2 it goes to the else statement?
else if (array2_search != array2_search + 45) {
Should be
else if (array2_search != array2 + 45) {
or better using std::end of C++11:
if (array1_search != std::end(array1)) {
else if (array2_search != std::end(array2)) {
And int gas; => double gas; if you want to be able to store floating point values, not just integers (0.2387 and 0.2710 would give integer 0).
Using standard containers and newer c++ features if you have C++11 minimum you can then do something like this:
int main() {
// Use Constants Instead of "Hard Coded Values"
// If you noticed these are not even needed.
// const unsigned code1 = 16;
// const unsigned code2 = 45;
// Made gas a float instead of an int due to the decimal values
// I also initialized it with the default value if the code is
// not found in either container.
float gas = 0.1506f; // Default Price If Not Found
// created your first array as a const std::vector<int> and
// used its initializer list to populate its contents: this vector
// can not be modified: remove the const if this container
// will need to have entries added in the future.
const std::vector<int> arr1 { 42011, 42017, 42029, 42045,
42091, 42101, 34001, 34005,
34007, 34009, 34011, 34015,
34033, 10001, 10003, 24015 }; // 0.2387 (23.87%)
// did the same for the second array
const std::vector<int> arr2 { 11001, 24003, 24510, 24005, 24009,
24013, 24017, 24019, 24021, 24025,
24027, 24029, 24031, 24033, 24035,
24037, 24041, 24043, 51510, 51013,
51043, 51047, 51600, 51059, 51610,
51061, 51069, 51630, 51099, 51107,
51683, 51685, 51153, 51157, 51177,
51179, 51187, 51840, 54003, 54027,
54037, 54065, 42001, 42055, 42133 }; //0.2710 (27.10%)
// No changes made here same basic user I/O.
int user_code = 0;
std::cout << "Please enter the Code: ";
std::cin >> user_code;
std::cout << "The value you entered is " << user_code;
std::cout << "\n";
// Created 2 flags for later.
bool b1found = false;
bool b2found = false;
// auto for loop ranged based.
for ( auto code : arr1 ) {
if ( code == user_code ) {
b1found = true; // Set flag
gas = 0.2387f; // Set new gas
// Output code & gas
std::cout << "Code found in Arr1: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
for ( auto code : arr2 ) {
if ( code == user_code ) {
b2found = true; // set flag
gas = 0.2710f; // set gas
// output code & gas
std::cout << "Code found in Arr2: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
// If code not found in either output "not found" and display default gas
if ( !b1found && !b2found ) {
std::cout << "Not found\n";
std::cout << "gas = " << gas << '\n';
}
std::cout << "\nPress any key and enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
You can even simplify this a little more by removing the two bool flags. We know that if a value is found in arr1 or arr2 that the gas value will be changed, So all we really have to do is check to see if it has been changed.
// auto for loop ranged based.
for ( auto code : arr1 ) {
if ( code == user_code ) {
gas = 0.2387f; // Set new gas
// Output code & gas
std::cout << "Code found in Arr1: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
for ( auto code : arr2 ) {
if ( code == user_code ) {
gas = 0.2710f; // set gas
// output code & gas
std::cout << "Code found in Arr2: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
const float defaultGas = 0.1506;
// If code not found in either output "not found" and display default gas
if ( gas == defaultGas ) {
std::cout << "Not found\n";
std::cout << "gas = " << gas << '\n';
}

Char* input check if it is hex or dec and parse it into unsigned short using appropriate error handling and reporting

I am trying to parse the input into unsigned short. The input can be anything but we can only accept hex or decimal. It needs to fit into unsigned short therefore no negative values or over 0xffff (65535). Invalid values must report errors appropriately and with enough information using C++ features.
My attempt (but it doesn't check for invalid hex values e.g. 5xffff):
void parse_input(char *input, unsigned short &output)
{
std::string soutput(input);
int myint1;
try
{
myint1 = std::stoi(soutput, 0, 0);
if (myint1 > std::numeric_limits<unsigned short>::max())
{
std::cerr << "Value: " << myint1
<< " is out of bounds!" << std::endl;
exit(EXIT_FAILURE);
}
output = myint1;
}
catch (std::exception &e)
{
std::cerr << "exception caught: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
}
Another attempt which also doesn't do all that (and apparently usage of errno is not acceptable):
auto n = strtoul(argv[2], NULL, 0);
if (errno == ERANGE || n > std::numeric_limits<unsigned short>::max()) {
}
else {
}
So the actual question based on the above is, what is the most efficient and effective way to resolve this using C++ features? Please provide an example.
Many thanks in advance.
So the actual question based on the above is, what is the most efficient and effective way to resolve this using C++ features? Please provide an example.
As your input numbers seem to be distinguished using a 0x for hex input and no prefix for decimal numbers, here's a small solution using a custom I/O manipulator:
std::istream& hex_or_decimal(std::istream& is) {
char peek = is.peek();
int zero_count = 0;
while(peek == '0' || std::isspace(peek)) {
if(peek == '0') {
++zero_count;
}
// Consume 0 prefixes as they wont affect the result
char dummy;
is.get(dummy);
peek = is.peek();
if((peek == 'x' || zero_count) && zero_count <= 1) {
is.get(dummy);
is >> std::hex;
return is;
}
}
is >> std::dec;
return is;
}
And use that like:
int main()
{
std::istringstream iss { "5 0x42 33 044 00x777 0x55" };
short input = 0;
while(iss >> hex_or_decimal >> input) {
std::cout << std::dec << input
<< " 0x" << std::hex << input << std::endl;
}
if(iss.fail()) {
std::cerr << "Invalid input!" << std::endl;
}
}
The output is
5 0x5
66 0x42
33 0x21
44 0x2c
Invalid input!
See the live example here please.
Note:
The 5xfffff value is signalled as invalid after 5 was consumed correctly by the stream (see the demonstration here)
You can easily adapt that to your needs (e.g. throwing an exception at invalid input) using the std::istream standard capabilities and flags.
E.g.:
Thowing and catching exceptions
int main()
{
std::istringstream iss { "5 0x42 33 044 00x777 0x55" };
iss.exceptions(std::ifstream::failbit); // <<<
try {
short input = 0;
while(iss >> hex_or_decimal >> input) {
std::cout << std::dec << input
<< " 0x" << std::hex << input << std::endl;
}
}
catch (const std::ios_base::failure &fail) { <<<
std::cerr << "Invalid input!" << std::endl;
}
}

missing data in popen call

my program compiles without error and appears to run through all of the steps correctly. It is supposed to make a php call and return data. tcpdump does show the request going out so popen is being executed, but the receiving party never updates.
The only discrepancy I can find, is that the command variable appears to be missing data.
# .trol.o
market max price is 0.00638671 at position 0
php coin.php 155 0.006387
0.00638672
the second line in the output is the command I am sending to popen
cout << command << endl; -> php coin.php 155 0.006387
that number is supposed to be the same as the one under it 0.00638672
The number 6 and the number 2 have been chopped off somehow.
How do I get the correct data into my popen command?
code:
void mngr(){
//vector defs
vector<std::string> buydat;
vector<std::string> markdat;
vector<std::string> pricedat;
vector<std::string> purchaseid;
vector<double> doublePdat;
vector<double> doubleMdat;
doublePdat.reserve(pricedat.size());
doubleMdat.reserve(markdat.size());
char buybuff[BUFSIZ];
char command[70];
char sendbuy[12];
buydat = getmyData();
markdat = getmarketbuyData();
//string match "Buy" and send results to new vector with pricedat.push_back()
for(int b = 2; b < buydat.size(); b+=7){
if ( buydat[b] == "Buy" ) {
pricedat.push_back(buydat[b+1]);
}
}
transform(pricedat.begin(), pricedat.end(), back_inserter(doublePdat), [](string const& val) {return stod(val);});
transform(markdat.begin(), markdat.end(), back_inserter(doubleMdat), [](string const& val) {return stod(val);});
auto biggestMy = std::max_element(std::begin(doublePdat), std::end(doublePdat));
std::cout << "my max price is " << *biggestMy << " at position " << std::distance(std::begin(doublePdat), biggestMy) << std::endl;
auto biggestMark = std::max_element(std::begin(doubleMdat), std::end(doubleMdat));
std::cout << "market max price is " << *biggestMark << " at position " << std::distance(std::begin(doubleMdat), biggestMark) << std::endl;
if (biggestMy > biggestMark){
cout << "Biggest is Mine!" << endl;
}
else if (biggestMy < biggestMark){
//cout << "Biggest is market!";
*biggestMark += 0.00000001;
sprintf(sendbuy,"%f",*biggestMark);
sprintf(command, "php coin.php 155 %s",sendbuy);
FILE *markbuy = popen(command, "r");
if (markbuy == NULL) perror ("Error opening file");
while(fgets(buybuff, sizeof(buybuff), markbuy) != NULL){
size_t h = strlen(buybuff);
//clean '\0' from fgets
if (h && buybuff[h - 1] == '\n') buybuff[h - 1] = '\0';
if (buybuff[0] != '\0') purchaseid.push_back(buybuff);
}
cout << command << endl;
cout << *biggestMark << endl;
}
}
I would try to use long float format instead of float as the type of biggestMark should be evaluated as iterator across doubles. I mean try to change sprintf(sendbuy,"%f",*biggestMark); to sprintf(sendbuy,"%lf",*biggestMark);. Hope this would help.