Error codes OR'd together - bit-manipulation

I am having trouble figuring this one out and I could use some help. So the data sheet to some hardware says "The reported error code is the OR’d result of each detected error. Error codes are given in Table 3."
Table 3 is
0x00 -> No error
0x01 -> Power error
0x02 -> Receiver error
0x03 -> Transmitter error
The data sheet then shows an example.
Example :
(ETV001T0C) + checksum -> Test status 0x0C (Rx and Tx error)
0C is the error byte.
So my first question is - Is my math wrong? I have no idea where they are getting 0C from. I am pretty sure that 0x02 | 0x03 = 0x03. And second even if it was 0C how do you figure out what errors are in that?

The table is giving actually giving bit shift positions, as used by the << operator.
1 << 0x00 = 0001b (?) -> No error
1 << 0x01 = 0010b -> Power error
1 << 0x02 = 0100b -> Receiver error
1 << 0x03 = 1000b -> Transmitter error
Using python as a calculator:
>>> (1 << 2) | (1 << 3)
12
>>> hex((1 << 2) | (1 << 3))
'0xc'

Related

How do I send text from TextView to 'Export to PDF'?

I'm new to GTK4, an open source toolkit for C++ binding. I want to send text from current TextView buffer (from a saved file) to a PDF file using GTK libraries (gtkmm4), but couldn't get anything printed out.
This is the code I have started from reading the documentation:
void MainWindow:export_note() {
auto op = Gtk::PrintOperation::create();
// setup op
cout << save_file_path << endl;
string content = editor.get_buffer()->get_text();
ofstream out(work_dir + save_file_path);
out << content;
out.close();
curr_state = edit_file;
op->set_export_filename("test.pdf");
auto res = op->run(Gtk::PrintOperation::Action::EXPORT);
return;
}
This only exports to a blank PDF, but I'm expecting text to show up on PDF.
It looks like you are not using any binary application to attempt conversion from text to text/pdf or more commonly binary application/pdf. You cannot simply stuff text data into a container called Test.pdf
There are simple means to convert Text to PDF, traditionally by using PostScript Printer files, but more commonly recently using a PDF printer driver direct
so start at the most basic level Hello World needs a file something like this, where the body is built up from stacked vectors or font labelled strings at X&Y co-ordinates.
Test.pdf
%PDF-1.1
%âãÏÓ
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Kids [3 0 R]/Count 1/MediaBox [0 0 594 792]>>endobj
3 0 obj<</Type/Page/Parent 2 0 R/Resources<</Font<</F1<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>>>>>/Contents 4 0 R>>endobj
4 0 obj<</Length 81
>>
stream
BT /F1 18 Tf 036 740 Td (Hello) Tj ET
BT /F1 18 Tf 036 720 Td (World!) Tj ET
endstream
endobj xref
0 5
0000000000 65535 f
0000000019 00000 n
0000000063 00000 n
0000000137 00000 n
0000000267 00000 n
trailer<</Root 1 0 R /Size 5>>startxref
399 %%EOF

How to create in C or C++ the contents value of Sig type object for digital signature in PDF?

We are programmatically creating PDF using our in house lib (C++) by adding all the required objects so that PDF readers can render them properly.
Currently we are enhancing the lib to support digital signatures in PDF. Our users will use USB token or Windows certificates to sign the PDF.
On studying raw PDF file with digital signature, we were able to make sense of all the objects except for the contents of Sig type object.
18 0 obj
<<
/Type /Sig
/Filter /Adobe.PPKLite --> signature handler for authenticating the fields contents
/SubFilter /adbe.pkcs7.sha1 --> submethod of the handler
/Contents <....> --> signature token
/ByteRange [ 0 101241 105931 7981
] --> byte range for digest calc
/M (D:20210505094125+05'30') --> timestamp
/Reason ()
/Location ()
/ContactInfo ()
>>
endobj
We have referred
https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSigDC/Acrobat_DigitalSignatures_in_PDF.pdf
to understand what all constitutes the signature token.
We need direction on how to programmatically create the signature token for PDF using windows APIs. Currently we are not looking at 3rd party lib solutions.
Thanks in advance.
Update
We tried the following:
Updated our in-house PDF lib to support incremental updates so that digital signing related objects can be added. We added something like this apart from the obj# 18 mentioned above:
16 0 obj --> new Acroform obj
<<
/Fields [ 17 0 R ]
/SigFlags 3
>>
endobj
2 0 obj --> Updating root to add AcroForm
<<
/Type /Catalog
/Pages 3 0 R
/AcroForm 16 0 R
>>
endobj
17 0 obj --> new obj for signature field
<<
/T (SignatureField1)
/Type /Annot
/Subtype /Widget
/FT /Sig
/F 4
/Rect [ 270 159 503 201 ] --> field position. this will have image of sign
/P 5 0 R
/V 18 0 R
/AP <<
/N 19 0 R
>>
>>
endobj
5 0 obj --> updating existing page obj with Annots
<<
/Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 841 ]
/Resources 4 0 R
/Contents 6 0 R
/Annots [ 17 0 R ]
>>
endobj
18 0 obj
<<
/Type /Sig
/Filter /Adobe.PPKLite
/SubFilter /adbe.pkcs7.sha1 --> we tried with adbe.pkcs7.detached as well
/Contents <> --> updated contents using windows APIs
/ByteRange [ 0 100381 102645 7322
] --> updated ByteRange with right offsets and lengths
/M (D:20210610125837+05'30') --> sign verified time
/Reason ()
/Location ()
/ContactInfo ()
>>
endobj
19 0 obj --> new obj
<<
/Length 7
/BBox [ 0 0 233 42 ]
/Type /XObject
/Subtype /Form
/Resources <<
/XObject <<
/FRM 20 0 R
>>
>>
>>
stream
/FRM Do
endstream
endobj
20 0 obj --> new obj for image manipulation
<<
/Length 29
/Type /XObject
/Subtype /Form
/Resources <<
/XObject <<
/Im1 21 0 R
>>
>>
/BBox [ 0 0 233 42 ]
>>
stream
q 233 0 0 42 0 0 cm /Im1 Do Q
endstream
endobj
21 0 obj --> image obj which contains sign info. Generated by us
<<
/Length 6166
/Type /XObject
/Subtype /Image
/Width 372
/Height 82
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/Filter /DCTDecode
>>
stream
---------------------------------> image stream
endstream
endobj
xref --> updated xref
0 1
0000000000 65535 f
2 1
0000099954 00000 n
5 1
0000100172 00000 n
16 6
0000099901 00000 n
0000100020 00000 n
0000100297 00000 n
0000102944 00000 n
0000103096 00000 n
0000103271 00000 n
trailer --> updated trailer
<<
/Root 2 0 R
/Info 1 0 R
/Size 22
/ID [ <982AAACB948CE1AD9FDD976D177BF316> <982AAACB948CE1AD9FDD976D177BF316> ]
--> ID generated via windows API
/Prev 99491
>>
startxref
109605
%%EOF
For contents data, we used the below API:
bool SignMessageBySubjectName (BytePtr pMessage, ULong pMessageSize, StrPtr pSubjectName, CRYPT_DATA_BLOB * pSignBlob)
{
HCERTSTORE store_handle = NULL;
PCCERT_CONTEXT cert_context = NULL;
BYTE * signed_blob = NULL;
ULong signed_blob_size;
ULong message_size;
CRYPT_SIGN_MESSAGE_PARA signature_params;
BYTE * message;
pSignBlob->cbData = 0;
pSignBlob->pbData = NULL;
message = (BYTE *) pMessage;
message_size = (pMessageSize + 1) * sizeof(Char); //Size in bytes
const BYTE * message_array[] = {message};
DWORD message_array_size[1];
message_array_size[0] = message_size;
store_handle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
cert_context = CertFindCertificateInStore( store_handle, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0,
CERT_FIND_SUBJECT_STR, pSubjectName, NULL);
signature_params.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
signature_params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
signature_params.pSigningCert = cert_context;
signature_params.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
signature_params.HashAlgorithm.Parameters.cbData = NULL;
signature_params.cMsgCert = 1;
signature_params.rgpMsgCert = &cert_context;
signature_params.cAuthAttr = 0;
signature_params.dwInnerContentType = 0;
signature_params.cMsgCrl = 0;
signature_params.cUnauthAttr = 0;
signature_params.dwFlags = 0;
signature_params.pvHashAuxInfo = NULL;
signature_params.rgAuthAttr = NULL;
//Get size of signed message
CryptSignMessage(&signature_params, TRUE, 1, message_array, message_array_size,NULL, &signed_blob_size);
signed_blob = (BYTE *) Malloc(signed_blob_size);
CryptSignMessage(&signature_params, TRUE, 1, message_array, message_array_size, signed_blob, &signed_blob_size);
pSignBlob->cbData = signed_blob_size;
pSignBlob->pbData = signed_blob;
CertFreeCertificateContext(cert_context);
CertCloseStore(store_handle, CERT_CLOSE_STORE_FORCE_FLAG);
return true;
}
While using CryptSignMessage() with detached parameter as TRUE, we get a around 850 length sign token which we convert to hex and add in the contents part. It'll approximately be around 1700 chars.
In case of the image used in the Field newly added, we generated our own image and added it as a PDF obj.
For the ID in trailer part, we generated the same using API from Bcrypt.lib (BCryptGenRandom()), converted its output to hex and updated the ID part.
Listing out the steps we did:
We generated 2 buffers. Both buffers are identical with respect to all the PDF objects required, the ID generated from BCryptGenRandom() and ByteRange array updated with actual values. buffer1 has contents data as 0s for a definite length acting as a placeholder. buffer2 has empty contents data (/Contents <>)
buffer2 will be passed onto CryptSignMessage() to generate the sign token. This will be converted to hex.
The hex sign token will be added to contents part of buffer1 replacing the 0s based on its length.
buffer1 will be written to a PDF file.
When we did all these, and opened the PDF in readers, we got errors like
Signature is invalid
Document has been corrupted or altered since the signature was applied.
Error from a PDF Reader:
Detailed Error:
But with these errors too, the reader was able to identify the user, certificate, hash algorithm and signature algorithm used.
We think we need to somehow add timestamp data as part of the sign token so as to avoid this error. Or something else we would have missed.
PFA sample PDF here:https://drive.google.com/file/d/1Udog4AmGoq2ls3Tu3Wq5s2xU9LxaI3fH/view?usp=sharing
Kindly help us solve this issue. Thanks in advance.
We used a different set of APIs to make this work.
Pasting the code here:
bool SignatureHandler::SignMessageTest (BytePtr pMessage, ULong pMessageSize, StrPtr pSubjectName, CRYPT_DATA_BLOB * pSignBlob, LPSTR pOid, DWORD pFlag, DWORD pType)
{
HCERTSTORE store_handle = NULL;
PCCERT_CONTEXT cert_context = NULL;
BYTE * signed_blob = NULL;
ULong signed_blob_size = 0;
CRYPT_SIGN_MESSAGE_PARA signature_params;
BYTE * message;
BOOL rc;
pSignBlob->cbData = 0;
pSignBlob->pbData = NULL;
store_handle = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
cert_context = CertFindCertificateInStore (store_handle, (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), 0, CERT_FIND_SUBJECT_STR, pSubjectName, NULL);
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE a = 0;
DWORD ks = 0;
BOOL bfr = false;
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE PrivateKeys;
CERT_BLOB CertsIncluded;
CMSG_SIGNER_ENCODE_INFO Signers;
HCRYPTMSG hMsg;
rc = CryptAcquireCertificatePrivateKey (cert_context, 0, 0, &a, &ks, &bfr);
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo = {0};
SignerEncodeInfo.cbSize = sizeof (CMSG_SIGNER_ENCODE_INFO);
if (a)
SignerEncodeInfo.hCryptProv = a;
if (bfr)
PrivateKeys = a;
CERT_BLOB SignerCertBlob;
SignerCertBlob.cbData = cert_context->cbCertEncoded;
SignerCertBlob.pbData = cert_context->pbCertEncoded;
CertsIncluded = SignerCertBlob;
SignerEncodeInfo.cbSize = sizeof (CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = cert_context->pCertInfo;
SignerEncodeInfo.dwKeySpec = ks;
SignerEncodeInfo.HashAlgorithm.pszObjId = pOid;
SignerEncodeInfo.HashAlgorithm.Parameters.cbData = NULL;
SignerEncodeInfo.pvHashAuxInfo = NULL;
Signers = SignerEncodeInfo;
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo = {0};
SignedMsgEncodeInfo.cbSize = sizeof (CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = &Signers;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = &CertsIncluded;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;
signed_blob_size = 0;
signed_blob_size = CryptMsgCalculateEncodedLength ((PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), pFlag, pType, &SignedMsgEncodeInfo, 0, pMessageSize);
if (signed_blob_size) {
signed_blob_size *= 2;
hMsg = CryptMsgOpenToEncode (CERTIFICATE_ENCODING_TYPE,
pFlag,
pType,
&SignedMsgEncodeInfo,
0,
NULL);
if (hMsg) {
signed_blob = (BYTE *)malloc (signed_blob_size);
BOOL CU = CryptMsgUpdate (hMsg, (BYTE *)pMessage, (DWORD)pMessageSize, true);
if (CU) {
if (CryptMsgGetParam (
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
signed_blob, // Pointer to the BLOB
&signed_blob_size)) // Size of the BLOB
{
signed_blob = (BYTE *)realloc (signed_blob, signed_blob_size);
if (hMsg) {
CryptMsgClose (hMsg);
hMsg = 0;
}
}
}
if (hMsg)
CryptMsgClose (hMsg);
hMsg = 0;
}
}
CryptReleaseContext (a, 0);
pSignBlob->cbData = signed_blob_size;
pSignBlob->pbData = signed_blob;
CertFreeCertificateContext (cert_context);
CertCloseStore (store_handle, CERT_CLOSE_STORE_FORCE_FLAG);
return true;
}
The oid, flag and type we used are szOID_RSA_SHA1RSA, CMSG_DETACHED_FLAG and CMSG_SIGNED respectively.
On converting pSignBlob->pbData to hex and adding it to /Contents, the PDF and signature became valid when opened in PDF readers.
Ok, the signature container is embedded correctly.
But there are issues with the signature container itself:
Both in the SignedData.digestAlgorithms collection and in the SignerInfo.digestAlgorithm value you have used the OID of SHA1withRSA, but that is a full signature algorithm, not the mere digest algorithm SHA1 expected there.
Then the SHA1 hash of the signed bytes is BB78A402F7A537A34D6892B83881266501A691A8 but the hash you signed is 90E28B8A0D8E48691DAFE2BA10A4761FFFDCCD3D. This might be because you hash buffer2 and
buffer2 has empty contents data (/Contents <>)
The hex string delimiters '<' and '>' also belong to the contents value and, therefore, must also be removed in buffer2.
Furthermore, your signature is very weak:
It uses SHA1 as hash algorithm. SHA1 meanwhile has been recognized as too weak a hash algorithm for document signatures.
It doesn't use signed attributes, neither the ESS signing certificate nor the algorithm identifier protection attribute. Many validation policies require such special attributes.

how to omit the carry bit in the hexa decimal addition

I am getting input from user as string, The string is converted into hex and that values are printed.. the code is as follows..
STX = input("enter STX Value")
Deviceid = input("enter device id")
subid = input("enter address of the Device and load details")
Comnd = "41"
Data = "01"
load = input("enter the load should be on or OFF,if on type 01 other wise type 00")
Eor = hex(int(STX, 16) ^ int(Deviceid, 16) ^ int(subid, 16) ^ int(Comnd, 16) ^ int(Data, 16) ^ int(load, 16))
Addsum = int(STX, 16)+int(Deviceid, 16)+int(subid, 16)+int(Comnd, 16)+int(Data, 16)+int(load, 16)+int(Eor, 16)
The output of the program is as follows
enter STX Value"F7"
enter device id"03"
enter address of the Device and load details"83"
enter the load should be on or OFF,if on type 01 other wise type 00"01"
0x36
the add sum is
0x1f6
In the last line 0x1f6 i want omit '1'. how can i do that.. thanks for your help...
You can use the modulo operator % to get the last two digits and then convert that number back to hexadecimal format, using either the hex function or a format string.
>>> m = 0x106 % 16**2
>>> print("0x%02x" % m)
0x06

Output Generation with GraphViz

I am supposed to write output into a text file with C++ and then process it using GraphViz.
This extract from my code:
cout << " " << i << " -> " << j
shows this error when I run it:
Error: MyGraph5V20E:4: syntax error near line 4
context: 0 >>> - <<< > 1 [label="73"];
And this is the output file:
graph G {
node [shape=circle]
0 -> 1 [label="73"];
0 -> 2 [label="60"];
0 -> 3 [label="36",color=red];
0 -> 4 [label="71"];
1 -> 2 [label="50",color=red];
1 -> 3 [label="78"];
1 -> 4 [label="85"];
2 -> 3 [label="30",color=red];
2 -> 4 [label="23",color=red];
3 -> 4 [label="68"];
}
I suppose it has to do with " -> " in my code. How can I manouvre this??

My whole parsing logic suffers because of null character how to resolve this

This is DATA 1
RE00002200050046\00 0.00 0.1 0.125.9\0#####- 14 0##### \0 0##### 141.0\004.00 0: 00.000.0\00 4: 011:27 0: 015:27#\0###########2.00.0\0
Another data that i have is
This is DATA 2
RE000022601\0500460 0.00 0.1\0 0.236.8####\0# 57- 2#####- 3#####\0- 601.004.0\00 4: 00.000.\000 4: 013:37 0\0: 017:37#####\0#######2.00.\00
The above data is the response i get from an hospital machine,i have to parse the above values and fill it according to given format:-
BYTEs 2 2 4 128 2 2
+---------+--------+------------+-----------------+--------+-------+
| RE | 00 | machine no| Data part | Check | CRC |
| | | | | sum | |
+---------+--------+------------+-----------------+--------+-------+
As you can see from DATA 1 My data part begins from "000500.."
and DATA 2 My data part begins from "601\0500..."
While doing parsing i got into a problem that there is field named "Blood pump flow" whose length is 3 bytes from the "DATA 1" we get its value as "46" while from the
"DATA 2" i got its value as "460".
In actual its value should be "460"
If i get a data like DATA 1 my whole parsing logic suffers as because as "Blood pump flow" is "3 bytes" i get a value "46\0" and "0" is added to another field while "Blood pump flow" should be "460".
The above is just one case i get it many times for some other fields too.
How to resolve this problem.
DATA 1 and DATA 2 are the binary data that i get from the machine.
It seems from your example, and it is confirmed by your own comment, that you know the field sizes in your format. So you must treat this input as binary input. Use std::istream::read function.
unsigned char header[14];
is.read(header,14);
if (is.gcount() == 14)
{
// decide which DATA1 or DATA2 you read from header contents
if (header is for DATA1)
// read rest of input as DATA1
// decide which DATA1 or DATA2 you read from header contents
else if (header is for DATA2)
// read rest of input as DATA2
else
//report error
}