github.com/etsc3259/etsc@v0.0.0-20190109113336-a9c2c10f9c95/internal/build/pgp.go (about)

     1  // Copyright 2016 The go-etsc Authors
     2  // This file is part of the go-etsc library.
     3  //
     4  // The go-etsc library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-etsc library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-etsc library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // signFile reads the contents of an input file and signs it (in armored format)
    18  // with the key provided, placing the signature into the output file.
    19  
    20  package build
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"os"
    26  
    27  	"golang.org/x/crypto/openpgp"
    28  )
    29  
    30  // PGPSignFile parses a PGP private key from the specified string and creates a
    31  // signature file into the output parameter of the input file.
    32  //
    33  // Note, this method assumes a single key will be container in the pgpkey arg,
    34  // furthermore that it is in armored format.
    35  func PGPSignFile(input string, output string, pgpkey string) error {
    36  	// Parse the keyring and make sure we only have a single private key in it
    37  	keys, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(pgpkey))
    38  	if err != nil {
    39  		return err
    40  	}
    41  	if len(keys) != 1 {
    42  		return fmt.Errorf("key count mismatch: have %d, want %d", len(keys), 1)
    43  	}
    44  	// Create the input and output streams for signing
    45  	in, err := os.Open(input)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	defer in.Close()
    50  
    51  	out, err := os.Create(output)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	defer out.Close()
    56  
    57  	// Generate the signature and return
    58  	return openpgp.ArmoredDetachSign(out, keys[0], in, nil)
    59  }
    60  
    61  // PGPKeyID parses an armored key and returns the key ID.
    62  func PGPKeyID(pgpkey string) (string, error) {
    63  	keys, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(pgpkey))
    64  	if err != nil {
    65  		return "", err
    66  	}
    67  	if len(keys) != 1 {
    68  		return "", fmt.Errorf("key count mismatch: have %d, want %d", len(keys), 1)
    69  	}
    70  	return keys[0].PrimaryKey.KeyIdString(), nil
    71  }