iText detached signature means - itext

Could you please explain me more in details eventually giving me some example (one for attached and one for detached) of what iText detached signature exactly means?
I found this wonderful documentation: iText digital signature pdf about iText digital signature but I'm still not sure I understand the iText detached signature concept.
Reading the documentation (see the link) I found this definition:
In PDF, we sometimes refer to a detached signature. According to Wikipedia, a detached signature is a type of digital signature that is kept ‘separate from its signed data’, as opposed to ‘bundled together into a single file’. This definition isn’t entirely correct in the context of PDF: the signature is enclosed in the PDF file, but the attributes of the signature are ‘part of the signature’, as opposed to ‘stored in the signature dictionary’.
where is not clear for me what "attributes of the signature" means (what signature attributes it's refer?)
Note that the author of the article (iText documentation) is working with this snippets of a signed PDF file:
%PDF-1.4
%âãÏÓ
3 0 obj
<</F 132/Type/Annot/Subtype/Widget/Rect[0 0 0 0]/FT/Sig
/DR<<>>/T(signature)/V 1 0 R/P 4 0 R/AP<</N 2 0 R>>>>
endobj
1 0 obj
<</Contents <0481801e6d931d561563fb254e27c846e08325570847ed63d6f9e35 ... b2c8788a5>
/Type/Sig/SubFilter/adbe.pkcs7.detached/Location(Ghent)/M(D:20120928104114+02'00')
/ByteRange [0 160 16546 1745 ]/Filter/Adobe.PPKLite/Reason(Test)/ContactInfo()>>
endobj
...
9 0 obj
<</Length 63>>stream
q
BT
36 806 Td
0 -18 Td
/F1 12 Tf
(Hello World!)Tj
0 0 Td
ET
Q
endstream
endobj
...
11 0 obj
<</Type/Catalog/AcroForm<</Fields[3 0 R]/DR<</Font<</Helv 5 0 R
/ZaDb 6 0 R>>>>/DA(/Helv 0 Tf 0 g )/SigFlags 3>>/Pages 10 0 R>>
endobj
xref
0 12
0000000000 65535 f
...
0000017736 00000 n
trailer
<</Root 11 0 R/ID [<08ed1afb8ac41e841738c8b24d592465><bd91a30f9c94b8facf5673e7d7c998dc>]/Info 7 0 R/Size 12>>
startxref
17879
%%EOF

While the white paper you quoted from, Digital Signatures for PDF documents by Bruno Lowagie, indeed is a must-read for anyone attempting to create integrated PDF signatures using iText (and a good source of information even if you are not using iText), I concur that the explanation therein of the use of the word "detached" in "detached PDF signature" doesn't really hit home:
NOTE: In PDF, we sometimes refer to a detached signature. According to Wikipedia, a
detached signature is a type of digital signature that is kept ‘separate from its signed data’, as
opposed to ‘bundled together into a single file’. This definition isn’t entirely correct in the
context of PDF: the signature is enclosed in the PDF file, but the attributes of the signature
are ‘part of the signature’, as opposed to ‘stored in the signature dictionary’.
First of all, calling these signatures "detached" is not a term enforced by any current specification. The reason why we do so anyway, is that the identifier used in the signature dictionaries of such signatures (adbe.pkcs7.detached or ETSI.CAdES.detached) contains that word.
Thus, the question actually should be: Why do these identifiers contain the word "detached"?
To understand this one needs to know that originally there were two kinds of integrated PDF signatures which embed a PKCS#7 signature container into the PDF, respectively identified by adbe.pkcs7.detached and adbe.pkcs7.sha1.
The difference between these two types of signatures is that
for adbe.pkcs7.sha1 signatures a SHA1 digest for the signed byte ranges of the PDF is calculated and embedded in the ContentInfo structure of the signature container and this embedded data packet is signed in the PKCS#7 way;
for adbe.pkcs7.detached signatures, on the other hand, the ContentInfo structure of the signature container is left empty and the signed data ranges of the external document are signed in the PKCS#7 way.
Thus, in case of adbe.pkcs7.sha1 signatures the actually signed data are embedded in the container while in case of adbe.pkcs7.detached signatures the actually signed data are not.
Thus, on the level of the PKCS#7 signature containers signed data and signature are detached from each other in the latter case.
(The fact that signing in the PKCS#7 way can --- and usually does --- include calculating a hash of the data to sign, adding this hash to a number of so-called authenticated attributes, and eventually signing these special attributes, shouldn't distract us.)
The other type of detached signatures (ETSI.CAdES.detached) are constructed similarly to the adbe.pkcs7.detached containers. The differences between them mostly are the profiling of additional attributes of the container.
The white paper's argumentation concerning attributes being part of the signature container actually illustrate the difference between all the signature types mentioned before and adbe.x509.rsa_sha1 signatures which is the third original integrated PDF signature type. This type is not based on signature containers but fairly naked signatures; thus, any extra information in that case has to be stored in their own structures in the PDF

Related

Why does Blockcypher signer tool return some extra characters than bip32 dart package?

I'm trying to sign a transaction skeleton Blockcypher returns, in order to send it along, following https://www.blockcypher.com/dev/bitcoin/#creating-transactions.
For this example, I'll use the completely-unsafe 'raw raw raw raw raw raw raw raw raw raw raw raw' mnemonic, which using dart bip32 package creates a BIP32 with private key 0x05a2716a8eb37eb2aaa72594573165349498aa6ca20c71346fb15d82c0cbbf7c and address mpQfiFFq7SHvzS9ebxMRGVohwHTRJJf9ra for BTC testnet.
Blockcypher Tx Skeleton tosign is 1cbbb4d229dcafe6dc3363daab8de99d6d38b043ce62b7129a8236e40053383e.
Using Blockcypher signer tool:
$ ./signer 1cbbb4d229dcafe6dc3363daab8de99d6d38b043ce62b7129a8236e40053383e 05a2716a8eb37eb2aaa72594573165349498aa6ca20c71346fb15d82c0cbbf7c
304402202711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4022058f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
On the other hand, using bip32 I get:
String toSign = txSkel['tosign'][0];
var uToSign = crypto.hexToBytes(toSign);
var signed = fromNode.sign(uToSign);
var signedHex = bufferToHex(signed);
var signedHexNo0x = signedHex.substring(2);
where fromNode is the bip32.BIP32 node. Output is signedHexNo0x = 2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc458f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab.
At first sight, they seem completely different buffers, but after a detailed look, Blockcypher signer output only has some extra characters than that of bip32:
Blockcypher signer output (I split it into several lines for you to see it clearly):
30440220
2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4
0220
58f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
bip32 output (also intentionally split):
2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4
58f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
I'd expect two 64-character numbers to give a 128-characters signature, which bip32 output accomplishes. Hence, Blockcypher signer output has 140 characters, i.e. 12 more than the former, which is clear when seen as split into lines as above.
I'd be really thankful to anyone throwing some light on this issue, which I need to understand and correct. I need to implement the solution in dart, I cannot use the signer script other than for testing.
The dart bip32 package doesn't seem to encode the signature in DER format, but rather in a simple (r, s) encoding. However DER is required for Bitcoin. For more information see:
https://bitcoin.stackexchange.com/questions/92680/what-are-the-der-signature-and-sec-format
You can either add the DER extra bytes yourself according to your r and s or check if there's a DER encoding in the dart bip32 library.

What does the Time (0040,A122) tag mean in DICOM header?

I have some trouble understanding the value of Time (0040,A122) tag. I am trying to update an anonymization software, but I can't seem to find any example of the actual tag.
The DICOM standard (PS 3.3) mentions that:
This is the Value component of a Name/Value pair when the Concept implied by Concept Name Code Sequence (0040,A043) is a time.
Note
The purpose or role of the date value could be specified in Concept Name Code Sequence (0040,A043).
Required if the value that Concept Name Code Sequence (0040,A043) requires (implies) is a time. Shall not be present otherwise.
So basically Concept Name Code Sequence (0040,A043) specifies what type of time it is? I would like to know what are some examples of Concept Name Code Sequence?
I would suggest to have a look at the SR sample given from the DICOM standard section PS 3.20:
A.7.2 Target DICOM SR "Measurement Report" (TID 1500)
In particular:
>>>>1.5.1.1.4: HAS ACQ CONTEXT: TIME: (111061,DCM,"Study Time") = "070844"
You may also want to check PS 3.16 for the definition of TID 1500:
TID 1500 Measurement Report
Just as a reminder, Enhanced SR are defined in PS 3.3:
A.35.2 Enhanced SR IOD

encryption mechanism used by pgp_sym_encrypt function

I am using pgp_sym_encrypt function to encrypt data in a postgresql column. What is the type of encryption being used by this function? Is there a way to change the encryption type?
Directly from the documentation:
F.26.3.8. Options for PGP Functions
Options are named to be similar to GnuPG. An option's value should be
given after an equal sign; separate options from each other with
commas. For example:
pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')
All of the options except convert-crlf apply only to encrypt
functions. Decrypt functions get the parameters from the PGP data.
The most interesting options are probably compress-algo and
unicode-mode. The rest should have reasonable defaults.
F.26.3.8.1. cipher-algo
Which cipher algorithm to use.
Values: bf, aes128, aes192, aes256 (OpenSSL-only: 3des, cast5)
Default: aes128
Applies to: pgp_sym_encrypt, pgp_pub_encrypt
F.26.3.8.2. compress-algo
Which compression algorithm to use. Only available if PostgreSQL was
built with zlib.
Values: 0 - no compression
1 - ZIP compression
2 - ZLIB compression (= ZIP plus meta-data and block CRCs)
Default: 0
Applies to: pgp_sym_encrypt, pgp_pub_encrypt
I believe it uses aes-128 by default, but this might depend on the version. It has been aes-128 since at least version 8.3.

COBOL add 0 to a Variable in COMPUTE

I ran into a strange statement when working on a COBOL program from $WORK.
We have a paragraph that is opening a cursor (from DB2), and the looping over it until it hits an EOT (in pseudo code):
... working storage ...
01 I PIC S9(9) COMP VALUE ZEROS.
01 WS-SUB PIC S9(4) COMP VALUE 0.
... code area ...
PARA-ONE.
PERFORM OPEN-CURSOR
PERFORM FETCH-CURSOR
PERFORM VARYING I FROM 1 BY 1 UNTIL SQLCODE = DB2EOT
do stuff here...
END-PERFORM
COMPUTE WS-SUB = I + 0
PERFORM CLOSE-CURSOR
... do another loop using WS-SUB ...
I'm wondering why that COMPUTE WS-SUB = I + 0 line is there. My understanding is that I will always at least be 1, because of the perform block above it (i.e., even if there is an EOT to start with, I will be set to one on that initial iteration).
Is that COMPUTE line even needed? Is it doing some implicit casting that I'm not aware of? Why would it be there? Why wouldn't you just MOVE I TO WS-SUB?
Call it stupid, but with some compilers (with the correct options in effect), given
01 SIGNED-NUMBER PIC S99 COMP-5 VALUE -1.
01 UNSIGNED-NUMBER PIC 99 COMP-5.
...
MOVE SIGNED-NUMBER TO UNSIGNED-NUMBER
DISPLAY UNSIGNED-NUMBER
results in: 255. But...
COMPUTE UNSIGNED-NUMBER = SIGNED-NUMBER + ZERO
results in: 1 (unsigned)
So to answer your question, this could be classified as a technique used cast signed numbers into unsigned numbers. However, in the code example you gave it makes no sense at all.
Note that the definition of "I" was (likely) coded by one programmer and of WS-SUB by another (naming is different, VALUE clause is different for same purpose).
Programmer 2 looks like "old school": PIC S9(4), signed and taking up all the digits which "fit" in a half-word. The S9(9) is probably "far over the top" as per range of possible values, but such things concern Programmer 1 not at all.
Probably Programmer 2 had concerns about using an S9(9) COMP for something requiring (perhaps many) fewer than 9999 "things". "I'll be 'efficient' without changing the existing code". It seems to me unlikely that the field was ever defined as unsigned.
A COMP/COMP-4 with nine digits does have a performance penalty when used for calculations. Try "ADD 1" to a 9(9) and a 9(8) and a 9(10) and compare the generated code. If you can have nine digits, define with 9(10), otherwise 9(8), if you need a fullword.
Programmer 2 knows something of this.
The COMPUTE with + 0 is probably deliberate. Why did Programmer 2 use the COMPUTE like that (the original question)?
Now it is going to get complicated.
There are two "types" of "binary" fields on the Mainframe: those which will contain values limited by the PICture clause (USAGE BINARY, COMP and COMP-4); those which contain values limited by the field size (USAGE COMP-5).
With BINARY/COMP/COMP-4, the size of the field is determined from the PICture, and so are the values that can be held. PIC 9(4) is a halfword, with a maxiumum value of 9999. PIC S9(4) a halfword with values -9999 through +9999.
With COMP-5 (Native Binary), the PICture just determines the size of the field, all the bits of the field are relevant for the value of the field. PIC 9(1) to 9(4) define halfwords, pic 9(5) to 9(9) define fullwords, and 9(10) to 9(18) define doublewords. PIC 9(1) can hold a maximum of 65535, S9(1) -32,768 through +32,767.
All well and good. Then there is compiler option TRUNC. This has three options. STD, the default, BIN and OPT.
BIN can be considered to have the most far-reaching affect. BIN makes BINARY/COMP/COMP-4 behave like COMP-5. Everything becomes, in effect, COMP-5. PICtures for binary fields are ignored, except in determining the size of the field (and, curiously, with ON SIZE ERROR, which "errors" when the maxima according to the PICture are exceeded). Native Binary, in IBM Enterprise Cobol, generates, in the main, though not exclusively, the "slowest" code. Truncation is to field size (halfword, fullword, doubleword).
STD, the default, is "standard" truncation. This truncates to "PICture". It is therefore a "decimal" truncation.
OPT is for "performance". With OPT, the compiler truncates in whatever way is the most "performant" for a particular "code sequence". This can mean intermediate values and final values may have "bits set" which are "outside of the range" of the PICture. However, when used as a source, a binary field will always only reflect the value specified by the PICture, even if there are "excess" bits set.
It is important when using OPT that all binary fields "conform to PICture" meaning that code must never rely on bits which are set outside the PICture definition.
Note: Even though OPT has been used, the OPTimizer (OPT(STD) or OPT(FULL)) can still provide further optimisations.
This is all well and good.
However, a "pickle" can readily ensue if you "mix" TRUNC options, or if the binary definition in a CALLing program is not the same as in the CALLed program. The "mix" can occur if modules within the same run-unit are compiled with different TRUNC options, or if a binary field on a file is written with one TRUNC option and later read with another.
Now, I suspect Programmer 2 encountered something like this: Either, with TRUNC(OPT) they noticed "excess bits" in a field and thought there was a need to deal with them, or, through the "mix" of options in a run-unit or "across file usage" they noticed "excess bits" where there would be a need to do something about it (which was to "remove the mix").
Programmer 2 developed the COMPUTE A = B + 0 to "deal" with a particular problem (perceived or actual) and then applied it generally to their work.
This is a "guess", or, better, a "rationalisation" which works with the known information.
It is a "fake" fix. There was either no problem (the normal way that TRUNC(OPT) works) or the correct resolution was "normalisation" of the TRUNC option across modules/file use.
I do not want loads of people now rushing off and putting COMPUTE A = B + 0 in their code. For a start, they don't know why they are doing it. For a continuation it is the wrong thing to do.
Of course, do not just remove the "+ 0" from any of these that you find. If there is a "mix" of TRUNCs, a program may stop "working".
There is one situation in which I have used "ADD ZERO" for a BINARY/COMP/COMP-4. This is in a "Mickey Mouse" program, a program with no purpose but to try something out. Here I've used it as a method to "trick" the optimizer, as otherwise the optimizer could see unchanging values so would generate code to use literal results as all values were known at compile time. (A perhaps "neater" and more flexible way to do this which I picked up from PhilinOxford, is to use ACCEPT for the field). This is not the case, for certain, with the code in question.
I wonder if a testing version of the sources ever had
COMPUTE WS-SUB = I + 0
ON SIZE ERROR
DISPLAY "WS-SUB overflow"
STOP RUN
END-COMPUTE
with the range test discarded when the developer was satisfied and cleaning up? MOVE doesn't allow declarative SIZE statements. That's as much of a reason as I could see. Or perhaps developer habit of using COMPUTE to move, as a subtle reminder to question the need for defensive code at every step? And perhaps not knowing, as Joe pointed out, the SIZE clause would be just as effective without the + 0? Or a maintainer struggled with off by one errors and there was a corrective change from 1 to 0 after testing?

Need to replace use of strcpy_s in C code used in iPhone project

I have a C SDK I need to use in an iPhone project, and the example code was written for use with Visual Studio. It includes use of strcpy_s, which is a Microsoft-only string function.
file_header.header_size = FIT_FILE_HDR_SIZE;
strcpy_s((FIT_UINT8 *)&file_header.data_type, sizeof(".FIT"), ".FIT"); << problem!
I've tried changing to strcpy and strncpy like so
strncpy((FIT_UINT8 *)&file_header.data_type, ".FIT", sizeof(".FIT"));
But I get this warning:
warning: pointer targets in passing argument 1 of 'builtin_strncpy_chk' differ in signedness
warning: pointer targets in passing argument 1 of '__inline_strncpy_chk' differ in signedness
warning: call to builtin_strncpy_chk will always overflow destination buffer
The struct file_header is this:
typedef struct
{
FIT_UINT8 header_size; // FIT_FILE_HDR_SIZE (size of this structure)
FIT_UINT8 protocol_version; // FIT_PROTOCOL_VERSION
FIT_UINT16 profile_version; // FIT_PROFILE_VERSION
FIT_UINT32 data_size; // Does not include file header or crc. Little endian format.
FIT_UINT8 data_type[4]; // ".FIT"
} FIT_FILE_HDR;
FIT_UINT8 is typedef Unsigned char.
So we can see that it is given an length of 4 in the typedef, and the strcpy_s takes the data_type by reference and copys ".FIT" to it. Where am I going wrong with strncpy? If you haven't guessed by now I'm not much of a C programmer :)
Edit: this does not give me an error, but it is correct?
strncpy((void *)&file_header.data_type, ".FIT", sizeof(file_header.data_type));
With any "safe string" operations, the size should almost always be the size of the destination buffer; if you use the size of the source string, you might as well call memcpy.
If you want C99 conformance:
strncpy(file_header.data_type, ".FIT", sizeof file_header.data_type);
However, strlcpy (a BSDism, available in iOS) is preferred by many, because it guarantees that the destination will be nul-terminated:
strlcpy(file_header.data_type, ".FIT", sizeof file_header.data_type);
Note, however that the nul-terminated string ".FIT" doesn't actually fit in the allotted space, as it requires 5 characters (1 for the trailing nul). If you use strlcpy, you will see that the resulting string is just ".FI" because strlcpy guarantees nul-termination, and truncates your string if necessary.
If you require nul-termination then, you probably want to increase the size of the data_type array to 5. As caf correctly points out, this looks like a file header, in which case nul-termination is probably not required; in that case strncpy is preferred; I might even use memcpy, and avoid giving a future developer the idea that the field is a string.
Don't use
sizeof(".FIT")
use
strlen(".FIT")