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