145 lines
2.9 KiB
Go
145 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"errors"
|
|
"io/ioutil"
|
|
|
|
"bitbucket.org/digitorus/pdfsign/revocation"
|
|
"bitbucket.org/digitorus/pdfsign/sign"
|
|
"bitbucket.org/digitorus/pdfsign/verify"
|
|
)
|
|
|
|
func usage() {
|
|
log.Fatal("Usage: sign input.pdf output.pdf certificate.crt private_key.key [chain.crt] OR verify input.pdf")
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if len(flag.Args()) < 2 {
|
|
usage()
|
|
}
|
|
|
|
method := flag.Arg(0)
|
|
if method != "sign" && method != "verify" {
|
|
usage()
|
|
}
|
|
|
|
input := flag.Arg(1)
|
|
if len(input) == 0 {
|
|
usage()
|
|
}
|
|
|
|
if method == "verify" {
|
|
input_file, err := os.Open(input)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer input_file.Close()
|
|
|
|
resp, err := verify.File(input_file)
|
|
log.Println(resp)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
if method == "sign" {
|
|
if len(flag.Args()) < 5 {
|
|
usage()
|
|
}
|
|
|
|
output := flag.Arg(2)
|
|
if len(output) == 0 {
|
|
usage()
|
|
}
|
|
|
|
certificate_data, err := ioutil.ReadFile(flag.Arg(3))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
|
|
}
|
|
certificate_data_block, _ := pem.Decode(certificate_data)
|
|
if certificate_data_block == nil {
|
|
log.Fatal(errors.New("failed to parse PEM block containing the certificate"))
|
|
}
|
|
|
|
cert, err := x509.ParseCertificate(certificate_data_block.Bytes)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
key_data, err := ioutil.ReadFile(flag.Arg(4))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
key_data_block, _ := pem.Decode(key_data)
|
|
if key_data_block == nil {
|
|
log.Fatal(errors.New("failed to parse PEM block containing the private key"))
|
|
}
|
|
|
|
pkey, err := x509.ParsePKCS1PrivateKey(key_data_block.Bytes)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
certificate_chains := make([][]*x509.Certificate, 0)
|
|
|
|
if flag.Arg(5) != "" {
|
|
certificate_pool := x509.NewCertPool()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
chain_data, err := ioutil.ReadFile(flag.Arg(5))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
certificate_pool.AppendCertsFromPEM(chain_data)
|
|
certificate_chains, err = cert.Verify(x509.VerifyOptions{
|
|
Intermediates: certificate_pool,
|
|
CurrentTime: cert.NotBefore,
|
|
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
err = sign.SignFile(input, output, sign.SignData{
|
|
Signature: sign.SignDataSignature{
|
|
Info: sign.SignDataSignatureInfo{
|
|
Name: "Jeroen Bobbeldijk",
|
|
Location: "Rotterdam",
|
|
Reason: "Test",
|
|
ContactInfo: "Geen",
|
|
Date: time.Now().Local(),
|
|
},
|
|
CertType: 2,
|
|
Approval: false,
|
|
},
|
|
Signer: pkey,
|
|
Certificate: cert,
|
|
CertificateChains: certificate_chains,
|
|
TSA: sign.TSA{
|
|
URL: "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23",
|
|
},
|
|
RevocationData: revocation.InfoArchival{},
|
|
RevocationFunction: sign.DefaultEmbedRevocationStatusFunction,
|
|
})
|
|
if err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
log.Println("Signed PDF written to " + output)
|
|
}
|
|
}
|
|
}
|