...

Source file src/github.com/sassoftware/relic/cmdline/token/importkeycmd.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  	"errors"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"os"
    24  
    25  	"github.com/sassoftware/relic/cmdline/shared"
    26  	"github.com/sassoftware/relic/lib/certloader"
    27  	"github.com/sassoftware/relic/lib/passprompt"
    28  	"github.com/sassoftware/relic/lib/x509tools"
    29  	"github.com/sassoftware/relic/signers/sigerrors"
    30  	"github.com/spf13/cobra"
    31  )
    32  
    33  var ImportKeyCmd = &cobra.Command{
    34  	Use:   "import-key",
    35  	Short: "Import a private key to a token",
    36  	RunE:  importKeyCmd,
    37  }
    38  
    39  var argPkcs12 bool
    40  
    41  func init() {
    42  	shared.RootCmd.AddCommand(ImportKeyCmd)
    43  	addKeyFlags(ImportKeyCmd)
    44  	ImportKeyCmd.Flags().StringVarP(&argToken, "token", "t", "", "Name of token to import key to")
    45  	ImportKeyCmd.Flags().StringVarP(&argLabel, "label", "l", "", "Label to attach to imported key")
    46  	ImportKeyCmd.Flags().StringVarP(&argFile, "file", "f", "", "Private key file to import: PEM, DER, or PGP")
    47  	ImportKeyCmd.Flags().BoolVar(&argPkcs12, "pkcs12", false, "Import a PKCS12 key and certificate chain")
    48  }
    49  
    50  func importKeyCmd(cmd *cobra.Command, args []string) error {
    51  	if argFile == "" {
    52  		return errors.New("--file is required")
    53  	}
    54  	blob, err := ioutil.ReadFile(argFile)
    55  	if err != nil {
    56  		return shared.Fail(err)
    57  	}
    58  	prompt := new(passprompt.PasswordPrompt)
    59  	var cert *certloader.Certificate
    60  	if argPkcs12 {
    61  		var err error
    62  		cert, err = certloader.ParsePKCS12(blob, prompt)
    63  		if err != nil {
    64  			return shared.Fail(err)
    65  		}
    66  	} else {
    67  		privKey, err := certloader.ParseAnyPrivateKey(blob, prompt)
    68  		if err != nil {
    69  			return shared.Fail(err)
    70  		}
    71  		cert = &certloader.Certificate{PrivateKey: privKey}
    72  	}
    73  	keyConf, err := newKeyConfig()
    74  	if err != nil {
    75  		return err
    76  	}
    77  	tok, err := openToken(keyConf.Token)
    78  	if err != nil {
    79  		return shared.Fail(err)
    80  	}
    81  	var didSomething bool
    82  	key, err := tok.GetKey(argKeyName)
    83  	if err == nil {
    84  		if cert.Leaf == nil {
    85  			return errors.New("An object with that label already exists in the token")
    86  		}
    87  		fmt.Fprintln(os.Stderr, "Private key already exists. Attempting to import certificates.")
    88  	} else if _, ok := err.(sigerrors.KeyNotFoundError); !ok {
    89  		return err
    90  	} else {
    91  		key, err = tok.Import(argKeyName, cert.PrivateKey)
    92  		if err != nil {
    93  			return err
    94  		}
    95  		didSomething = true
    96  	}
    97  	if cert.Leaf != nil {
    98  		name := x509tools.FormatSubject(cert.Leaf)
    99  		err := key.ImportCertificate(cert.Leaf)
   100  		if err == sigerrors.ErrExist {
   101  			fmt.Fprintln(os.Stderr, "Certificate already exists:", name)
   102  		} else if err != nil {
   103  			return shared.Fail(fmt.Errorf("failed to import %s: %s", name, err))
   104  		} else {
   105  			fmt.Fprintln(os.Stderr, "Imported", name)
   106  			didSomething = true
   107  		}
   108  		for _, chain := range cert.Chain() {
   109  			if chain == cert.Leaf {
   110  				continue
   111  			}
   112  			name = x509tools.FormatSubject(chain)
   113  			err = tok.ImportCertificate(chain, keyConf.Label)
   114  			if err == sigerrors.ErrExist {
   115  				fmt.Fprintln(os.Stderr, "Certificate already exists:", name)
   116  			} else if err != nil {
   117  				return shared.Fail(fmt.Errorf("failed to import %s: %s", name, err))
   118  			} else {
   119  				fmt.Fprintln(os.Stderr, "Imported", name)
   120  				didSomething = true
   121  			}
   122  		}
   123  	}
   124  	if !didSomething {
   125  		return shared.Fail(errors.New("nothing imported"))
   126  	}
   127  	fmt.Fprintln(os.Stderr, "Token CKA_ID: ", formatKeyID(key.GetID()))
   128  	return nil
   129  }
   130  

View as plain text