Compare commits
No commits in common. "a5176b5bbb1c38869fe4009eb73ecc23a4e18909" and "3ce08d33f6bad9931b32082f598b0e98599dd120" have entirely different histories.
a5176b5bbb
...
3ce08d33f6
9
NEWS
9
NEWS
@ -1,12 +1,3 @@
|
|||||||
1.1.1 (2020-09-06)
|
|
||||||
|
|
||||||
* Fix a dysfunctional example in the manual
|
|
||||||
|
|
||||||
* Go: write the xref table in a deterministic order
|
|
||||||
|
|
||||||
* Add a trivial test suite, based on pdfsig from poppler-utils
|
|
||||||
|
|
||||||
|
|
||||||
1.1 (2020-09-05)
|
1.1 (2020-09-05)
|
||||||
|
|
||||||
* Make it possible to change the signature reservation with an option
|
* Make it possible to change the signature reservation with an option
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
project('pdf-simple-sign', 'cpp', default_options : ['cpp_std=c++11'],
|
project('pdf-simple-sign', 'cpp', default_options : ['cpp_std=c++11'],
|
||||||
version : '1.1.1')
|
version : '1.1')
|
||||||
|
|
||||||
conf = configuration_data()
|
conf = configuration_data()
|
||||||
conf.set('PROJECT_NAME', '"' + meson.project_name() + '"')
|
conf.set('PROJECT_NAME', '"' + meson.project_name() + '"')
|
||||||
|
@ -50,11 +50,10 @@ Examples
|
|||||||
Create a self-signed certificate, make a document containing the current date,
|
Create a self-signed certificate, make a document containing the current date,
|
||||||
sign it and verify the attached signature:
|
sign it and verify the attached signature:
|
||||||
|
|
||||||
$ openssl req -newkey rsa:2048 -subj /CN=Test -nodes \
|
$ openssl req -newkey rsa:2048 -subj "/CN=Test" -nodes
|
||||||
-keyout key.pem -x509 -addext keyUsage=digitalSignature \
|
-keyout key.pem -x509 -out cert.pem 2>/dev/null
|
||||||
-out cert.pem 2>/dev/null
|
|
||||||
$ openssl pkcs12 -inkey key.pem -in cert.pem \
|
$ openssl pkcs12 -inkey key.pem -in cert.pem \
|
||||||
-export -passout pass: -out key-pair.p12
|
-export -passout pass:test -out key-cert.p12
|
||||||
$ date | groff -T pdf > test.pdf
|
$ date | groff -T pdf > test.pdf
|
||||||
$ pdf-simple-sign test.pdf test.signed.pdf key-pair.p12 ""
|
$ pdf-simple-sign test.pdf test.signed.pdf key-pair.p12 ""
|
||||||
$ pdfsig test.signed.pdf
|
$ pdfsig test.signed.pdf
|
||||||
|
36
pdf/pdf.go
36
pdf/pdf.go
@ -853,19 +853,30 @@ func (u *Updater) FlushUpdates() {
|
|||||||
return updated[i] < updated[j]
|
return updated[i] < updated[j]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
groups := make(map[uint]uint)
|
||||||
|
for i := 0; i < len(updated); {
|
||||||
|
start, count := updated[i], uint(1)
|
||||||
|
for i++; i != len(updated) && updated[i] == start+count; i++ {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
groups[start] = count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taking literally "Each cross-reference section begins with a line
|
||||||
|
// containing the keyword xref. Following this line are one or more
|
||||||
|
// cross-reference subsections." from 3.4.3 in PDF Reference.
|
||||||
|
if len(groups) == 0 {
|
||||||
|
groups[0] = 0
|
||||||
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(u.Document)
|
buf := bytes.NewBuffer(u.Document)
|
||||||
startXref := buf.Len() + 1
|
startXref := buf.Len() + 1
|
||||||
buf.WriteString("\nxref\n")
|
buf.WriteString("\nxref\n")
|
||||||
|
|
||||||
for i := 0; i < len(updated); {
|
for start, count := range groups {
|
||||||
start, stop := updated[i], updated[i]+1
|
fmt.Fprintf(buf, "%d %d\n", start, count)
|
||||||
for i++; i < len(updated) && updated[i] == stop; i++ {
|
for i := uint(0); i < count; i++ {
|
||||||
stop++
|
ref := u.xref[start+uint(i)]
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(buf, "%d %d\n", start, stop-start)
|
|
||||||
for ; start < stop; start++ {
|
|
||||||
ref := u.xref[start]
|
|
||||||
if ref.nonfree {
|
if ref.nonfree {
|
||||||
fmt.Fprintf(buf, "%010d %05d n \n", ref.offset, ref.generation)
|
fmt.Fprintf(buf, "%010d %05d n \n", ref.offset, ref.generation)
|
||||||
} else {
|
} else {
|
||||||
@ -874,13 +885,6 @@ func (u *Updater) FlushUpdates() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taking literally "Each cross-reference section begins with a line
|
|
||||||
// containing the keyword xref. Following this line are one or more
|
|
||||||
// cross-reference subsections." from 3.4.3 in PDF Reference.
|
|
||||||
if len(updated) == 0 {
|
|
||||||
fmt.Fprintf(buf, "%d %d\n", 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Trailer["Size"] = NewNumeric(float64(u.xrefSize))
|
u.Trailer["Size"] = NewNumeric(float64(u.xrefSize))
|
||||||
trailer := NewDict(u.Trailer)
|
trailer := NewDict(u.Trailer)
|
||||||
|
|
||||||
|
77
test.sh
77
test.sh
@ -1,77 +0,0 @@
|
|||||||
#!/bin/sh -e
|
|
||||||
# Test basic functionality of both versions
|
|
||||||
# Usage: ./test.sh builddir/pdf-simple-sign cmd/pdf-simple-sign/pdf-simple-sign
|
|
||||||
|
|
||||||
log() { echo "`tput sitm`-- $1`tput sgr0`"; }
|
|
||||||
die() { echo "`tput bold`-- $1`tput sgr0`"; exit 1; }
|
|
||||||
|
|
||||||
# Get rid of old test files
|
|
||||||
rm -rf tmp
|
|
||||||
mkdir tmp
|
|
||||||
|
|
||||||
# Create documents in various tools
|
|
||||||
log "Creating source documents"
|
|
||||||
inkscape --pipe --export-filename=tmp/cairo.pdf <<'EOF' 2>/dev/null || :
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"><text x="5" y="10">Hello</text></svg>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
date | tee tmp/lowriter.txt | groff -T pdf > tmp/groff.pdf || :
|
|
||||||
lowriter --convert-to pdf tmp/lowriter.txt --outdir tmp >/dev/null || :
|
|
||||||
convert rose: tmp/imagemagick.pdf || :
|
|
||||||
|
|
||||||
# Create a root CA certificate pair
|
|
||||||
log "Creating certificates"
|
|
||||||
openssl req -newkey rsa:2048 -subj "/CN=Test CA" -nodes \
|
|
||||||
-keyout tmp/ca.key.pem -x509 -out tmp/ca.cert.pem 2>/dev/null
|
|
||||||
|
|
||||||
# Create a private NSS database and insert our test CA there
|
|
||||||
rm -rf tmp/nssdir
|
|
||||||
mkdir tmp/nssdir
|
|
||||||
certutil -N --empty-password -d sql:tmp/nssdir
|
|
||||||
certutil -d sql:tmp/nssdir -A -n root -t ,C, -a -i tmp/ca.cert.pem
|
|
||||||
|
|
||||||
# Create a leaf certificate pair
|
|
||||||
cat > tmp/cert.cfg <<'EOF'
|
|
||||||
[smime]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
keyUsage = digitalSignature
|
|
||||||
extendedKeyUsage = emailProtection
|
|
||||||
nsCertType = email
|
|
||||||
EOF
|
|
||||||
|
|
||||||
openssl req -newkey rsa:2048 -subj "/CN=Test Leaf" -nodes \
|
|
||||||
-keyout tmp/key.pem -out tmp/cert.csr 2>/dev/null
|
|
||||||
openssl x509 -req -in tmp/cert.csr -out tmp/cert.pem \
|
|
||||||
-CA tmp/ca.cert.pem -CAkey tmp/ca.key.pem -set_serial 1 \
|
|
||||||
-extensions smime -extfile tmp/cert.cfg 2>/dev/null
|
|
||||||
openssl verify -CAfile tmp/ca.cert.pem tmp/cert.pem >/dev/null
|
|
||||||
openssl pkcs12 -inkey tmp/key.pem -in tmp/cert.pem \
|
|
||||||
-export -passout pass: -out tmp/key-pair.p12
|
|
||||||
|
|
||||||
for tool in "$@"; do
|
|
||||||
rm -f tmp/*.signed.pdf
|
|
||||||
for source in tmp/*.pdf; do
|
|
||||||
log "Testing $tool with $source"
|
|
||||||
result=${source%.pdf}.signed.pdf
|
|
||||||
$tool "$source" "$result" tmp/key-pair.p12 ""
|
|
||||||
pdfsig -nssdir sql:tmp/nssdir "$result" | grep Validation
|
|
||||||
done
|
|
||||||
|
|
||||||
log "Testing $tool for expected failures"
|
|
||||||
$tool "$result" "$source.fail.pdf" tmp/key-pair.p12 "" \
|
|
||||||
&& die "Double signing shouldn't succeed"
|
|
||||||
$tool -r 1 "$source" "$source.fail.pdf" tmp/key-pair.p12 "" \
|
|
||||||
&& die "Too low reservations shouldn't succeed"
|
|
||||||
|
|
||||||
# Our generators do not use PDF versions higher than 1.5
|
|
||||||
log "Testing $tool for version detection"
|
|
||||||
grep -q "/Version /1.6" "$result" \
|
|
||||||
|| die "Version detection seems to misbehave (no upgrade)"
|
|
||||||
|
|
||||||
sed '1s/%PDF-1../%PDF-1.7/' "$source" > "$source.alt"
|
|
||||||
$tool "$source.alt" "$result.alt" tmp/key-pair.p12 ""
|
|
||||||
grep -q "/Version /1.6" "$result.alt" \
|
|
||||||
&& die "Version detection seems to misbehave (downgraded)"
|
|
||||||
done
|
|
||||||
|
|
||||||
log "OK"
|
|
Loading…
x
Reference in New Issue
Block a user