183 lines
5.1 KiB
Go
183 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
|
|
"fmt"
|
|
|
|
"bitbucket.org/digitorus/pdfsign/config"
|
|
"bitbucket.org/digitorus/pdfsign/sign"
|
|
"bitbucket.org/digitorus/pdfsign/verify"
|
|
)
|
|
|
|
// usage is a usage function for the flags package.
|
|
func usage() {
|
|
fmt.Fprintf(os.Stderr, "Pdfsign is a tool to sign and verify PDF digital signatures\n\n")
|
|
fmt.Fprintf(os.Stderr, "Usage:\n\n")
|
|
fmt.Fprintf(os.Stderr, "\tpdfsign command [arguments]\n\n")
|
|
fmt.Fprintf(os.Stderr, "The commands are:\n\n")
|
|
fmt.Fprintf(os.Stderr, "\tsign \t\tsign single PDF document\n")
|
|
fmt.Fprintf(os.Stderr, "\tverify \t\tverify signature of single PDF document\n")
|
|
fmt.Fprintf(os.Stderr, "\tserve \t\tserve web API with signing capabilities. API documentation url\n")
|
|
fmt.Fprintf(os.Stderr, "\twatch \t\tautomatically sign PDF files inside a folder\n")
|
|
fmt.Fprintf(os.Stderr, "\n\n")
|
|
flag.PrintDefaults()
|
|
os.Exit(2)
|
|
}
|
|
|
|
func main() {
|
|
// if no flags provided print usage
|
|
if len(os.Args) == 1 {
|
|
usage()
|
|
return
|
|
}
|
|
|
|
switch os.Args[1] {
|
|
case "sign":
|
|
simpleSign()
|
|
case "verify":
|
|
verifyPDF()
|
|
case "serve":
|
|
case "watch":
|
|
default:
|
|
fmt.Printf("%q is not valid command.\n", os.Args[1])
|
|
os.Exit(2)
|
|
}
|
|
}
|
|
|
|
func verifyPDF() {
|
|
verifyCommand := flag.NewFlagSet("verify", flag.ExitOnError)
|
|
input := verifyCommand.String("in", "", "")
|
|
|
|
input_file, err := os.Open(*input)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer input_file.Close()
|
|
|
|
resp, err := verify.Verify(input_file)
|
|
log.Println(resp)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
func getSignDataFlags(f *flag.FlagSet) sign.SignData {
|
|
// Signature info
|
|
name := f.String("info-name", config.Settings.Info.Name, "Signature info name")
|
|
location := f.String("info-location", config.Settings.Info.Location, "Signature info location")
|
|
reason := f.String("info-reason", config.Settings.Info.Reason, "Signature info reason")
|
|
contact := f.String("info-contact", config.Settings.Info.ContactInfo, "Signature info contact")
|
|
// Signature other
|
|
approval := f.Bool("approval", false, "Approval")
|
|
certType := f.Uint("type", 0, "Certificate type")
|
|
|
|
// TSA
|
|
tsaUrl := f.String("tsa-url", "", "tsaUrl")
|
|
tsaUsername := f.String("tsa-username", "", "tsaUsername")
|
|
tsaPassword := f.String("tsa-password", "", "tsaPassword")
|
|
|
|
var sd sign.SignData
|
|
sd.Signature.Info.Name = *name
|
|
sd.Signature.Info.Location = *location
|
|
sd.Signature.Info.Reason = *reason
|
|
sd.Signature.Info.ContactInfo = *contact
|
|
sd.Signature.CertType = uint32(*certType)
|
|
sd.Signature.Approval = *approval
|
|
sd.TSA.URL = *tsaUrl
|
|
sd.TSA.Username = *tsaUsername
|
|
sd.TSA.Password = *tsaPassword
|
|
return sd
|
|
}
|
|
|
|
func simpleSign() {
|
|
signCommand := flag.NewFlagSet("sign", flag.ExitOnError)
|
|
configPath := signCommand.String("config", "", "Path to config file")
|
|
signCommand.Parse(os.Args[2:])
|
|
if *configPath != "" {
|
|
config.Read(*configPath)
|
|
}
|
|
|
|
inputPath := signCommand.String("in", "", "Input PDF file")
|
|
outputPath := signCommand.String("out", "", "Output PDF file")
|
|
crtPath := signCommand.String("crt", "", "Certificate")
|
|
keyPath := signCommand.String("key", "", "Private key")
|
|
crtChainPath := signCommand.String("chain", "", "Certificate chain")
|
|
help := signCommand.Bool("help", false, "Show this help")
|
|
signData := getSignDataFlags(signCommand)
|
|
signCommand.Parse(os.Args[2:])
|
|
|
|
usageText := `usage: pdfsign sign -in input.pdf -out output.pdf -crt certificate.crt -key private_key.key [-chain chain.crt]")
|
|
Description
|
|
`
|
|
if *help == true {
|
|
fmt.Println(usageText)
|
|
signCommand.PrintDefaults()
|
|
return
|
|
}
|
|
|
|
if signCommand.Parsed() == false || *inputPath == "" || *outputPath == "" || *crtPath == "" || *keyPath == "" {
|
|
fmt.Println(usageText)
|
|
signCommand.PrintDefaults()
|
|
os.Exit(2)
|
|
}
|
|
|
|
s, err := newSigner(*crtPath, *keyPath, *crtChainPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := s.sign(*inputPath, *outputPath, signData); err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
log.Println("Signed PDF written to " + *outputPath)
|
|
}
|
|
}
|
|
|
|
func p11sign() {
|
|
signCommand := flag.NewFlagSet("sign", flag.ExitOnError)
|
|
configPath := signCommand.String("config", "", "Path to config file")
|
|
signCommand.Parse(os.Args[2:])
|
|
if *configPath != "" {
|
|
config.Read(*configPath)
|
|
}
|
|
|
|
input := signCommand.String("in", "", "Input PDF file")
|
|
output := signCommand.String("out", "", "Output PDF file")
|
|
libPath := signCommand.String("lib", "", "Path to PKCS11 library")
|
|
pass := signCommand.String("pass", "", "PKCS11 password")
|
|
crtChainPath := signCommand.String("chain", "", "Certificate chain")
|
|
help := signCommand.Bool("help", false, "Show this help")
|
|
signData := getSignDataFlags(signCommand)
|
|
signCommand.Parse(os.Args[2:])
|
|
usageText := `Usage: pdfsign sign -in input.pdf -out output.pdf -pass pkcs11-password [-chain chain.crt]")
|
|
|
|
Description
|
|
|
|
`
|
|
if *help == true {
|
|
fmt.Println(usageText)
|
|
signCommand.PrintDefaults()
|
|
return
|
|
}
|
|
|
|
if signCommand.Parsed() == false || *input == "" || *output == "" || *pass == "" {
|
|
fmt.Println(usageText)
|
|
signCommand.PrintDefaults()
|
|
os.Exit(2)
|
|
}
|
|
|
|
s, err := newP11Signer(*libPath, *pass, *crtChainPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := s.sign(*input, *output, signData); err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
log.Println("Signed PDF written to " + *output)
|
|
}
|
|
}
|