...

Source file src/github.com/sassoftware/relic/cmdline/token/newpgpkeycmd.go

Documentation: github.com/sassoftware/relic/cmdline/token

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package token
    18  
    19  import (
    20  	"crypto"
    21  	"crypto/ecdsa"
    22  	"crypto/rsa"
    23  	"encoding/hex"
    24  	"errors"
    25  	"fmt"
    26  	"os"
    27  	"strings"
    28  	"time"
    29  
    30  	"github.com/sassoftware/relic/cmdline/shared"
    31  	"github.com/sassoftware/relic/token"
    32  	"github.com/spf13/cobra"
    33  	"golang.org/x/crypto/openpgp"
    34  	"golang.org/x/crypto/openpgp/armor"
    35  	"golang.org/x/crypto/openpgp/packet"
    36  )
    37  
    38  var NewPgpKeyCmd = &cobra.Command{
    39  	Use:   "pgp-generate",
    40  	Short: "Generate a new PGP key from token",
    41  	RunE:  newPgpKeyCmd,
    42  }
    43  
    44  var (
    45  	argUserName    string
    46  	argUserComment string
    47  	argUserEmail   string
    48  )
    49  
    50  func init() {
    51  	shared.RootCmd.AddCommand(NewPgpKeyCmd)
    52  	NewPgpKeyCmd.Flags().StringVarP(&argUserName, "name", "n", "", "Name of user identity")
    53  	NewPgpKeyCmd.Flags().StringVarP(&argUserComment, "comment", "C", "", "Comment of user identity")
    54  	NewPgpKeyCmd.Flags().StringVarP(&argUserEmail, "email", "E", "", "Email of user identity")
    55  	addSelectOrGenerateFlags(NewPgpKeyCmd)
    56  }
    57  
    58  func makeKey(key token.Key, uids []*packet.UserId) (*openpgp.Entity, error) {
    59  	creationTime := time.Now()
    60  	var pubKey *packet.PublicKey
    61  	switch pub := key.Public().(type) {
    62  	case *rsa.PublicKey:
    63  		pubKey = packet.NewRSAPublicKey(creationTime, pub)
    64  	case *ecdsa.PublicKey:
    65  		pubKey = packet.NewECDSAPublicKey(creationTime, pub)
    66  	default:
    67  		return nil, errors.New("Unsupported key type")
    68  	}
    69  	entity := &openpgp.Entity{
    70  		PrimaryKey: pubKey,
    71  		PrivateKey: &packet.PrivateKey{
    72  			PublicKey:  *pubKey,
    73  			Encrypted:  false,
    74  			PrivateKey: key,
    75  		},
    76  		Identities: make(map[string]*openpgp.Identity),
    77  	}
    78  	isPrimaryID := true
    79  	for _, uid := range uids {
    80  		sig := &packet.Signature{
    81  			SigType:      packet.SigTypePositiveCert,
    82  			CreationTime: creationTime,
    83  			PubKeyAlgo:   pubKey.PubKeyAlgo,
    84  			Hash:         crypto.SHA512,
    85  			IsPrimaryId:  &isPrimaryID,
    86  			FlagsValid:   true,
    87  			FlagSign:     true,
    88  			FlagCertify:  true,
    89  			IssuerKeyId:  &pubKey.KeyId,
    90  		}
    91  		err := sig.SignUserId(uid.Id, entity.PrimaryKey, entity.PrivateKey, nil)
    92  		if err != nil {
    93  			return nil, err
    94  		}
    95  		entity.Identities[uid.Id] = &openpgp.Identity{
    96  			Name:          uid.Name,
    97  			UserId:        uid,
    98  			SelfSignature: sig,
    99  		}
   100  	}
   101  	return entity, nil
   102  }
   103  
   104  func newPgpKeyCmd(cmd *cobra.Command, args []string) error {
   105  	if argUserName == "" {
   106  		return errors.New("--name is required")
   107  	}
   108  	uid := packet.NewUserId(argUserName, argUserComment, argUserEmail)
   109  	if uid == nil {
   110  		return errors.New("Invalid user ID")
   111  	}
   112  	key, err := selectOrGenerate()
   113  	if err != nil {
   114  		return err
   115  	}
   116  	entity, err := makeKey(key, []*packet.UserId{uid})
   117  	if err != nil {
   118  		return err
   119  	}
   120  	fingerprint := hex.EncodeToString(entity.PrimaryKey.Fingerprint[:])
   121  	fmt.Fprintln(os.Stderr, "Token CKA_ID: ", formatKeyID(key.GetID()))
   122  	fmt.Fprintln(os.Stderr, "PGP ID:       ", strings.ToUpper(fingerprint))
   123  	writer, err := armor.Encode(os.Stdout, openpgp.PublicKeyType, nil)
   124  	if err != nil {
   125  		return err
   126  	}
   127  	err = entity.Serialize(writer)
   128  	if err != nil {
   129  		return err
   130  	}
   131  	writer.Close()
   132  	fmt.Println()
   133  	return nil
   134  }
   135  

View as plain text