...

Source file src/github.com/sassoftware/relic/cmdline/token/common.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  	"os"
    23  	"strings"
    24  	"time"
    25  
    26  	"github.com/sassoftware/relic/cmdline/shared"
    27  	"github.com/sassoftware/relic/config"
    28  	"github.com/sassoftware/relic/lib/passprompt"
    29  	"github.com/sassoftware/relic/signers/sigerrors"
    30  	"github.com/sassoftware/relic/token"
    31  	"github.com/sassoftware/relic/token/open"
    32  	"github.com/spf13/cobra"
    33  )
    34  
    35  var (
    36  	argFile      string
    37  	argKeyName   string
    38  	argToken     string
    39  	argLabel     string
    40  	argRsaBits   uint
    41  	argEcdsaBits uint
    42  )
    43  
    44  var tokenMap map[string]token.Token
    45  
    46  func addKeyFlags(cmd *cobra.Command) {
    47  	cmd.Flags().StringVarP(&argKeyName, "key", "k", "", "Name of key section in config file to use")
    48  }
    49  
    50  func addSelectOrGenerateFlags(cmd *cobra.Command) {
    51  	addKeyFlags(cmd)
    52  	cmd.Flags().StringVarP(&argToken, "token", "t", "", "Name of token to generate key in")
    53  	cmd.Flags().StringVarP(&argLabel, "label", "l", "", "Label to attach to generated key")
    54  	cmd.Flags().UintVar(&argRsaBits, "generate-rsa", 0, "Generate a RSA key of the specified bit size, if needed")
    55  	cmd.Flags().UintVar(&argEcdsaBits, "generate-ecdsa", 0, "Generate an ECDSA key of the specified curve size, if needed")
    56  }
    57  
    58  // Update key config with values from --token and --label
    59  func newKeyConfig() (*config.KeyConfig, error) {
    60  	if err := shared.InitConfig(); err != nil {
    61  		return nil, err
    62  	}
    63  	var keyConf *config.KeyConfig
    64  	if argKeyName != "" {
    65  		var err error
    66  		keyConf, err = shared.CurrentConfig.GetKey(argKeyName)
    67  		if err != nil {
    68  			return nil, err
    69  		}
    70  	} else {
    71  		if argToken == "" || argLabel == "" {
    72  			return nil, errors.New("Either --key, or --token and --label, must be set")
    73  		}
    74  		argKeyName = fmt.Sprintf("new-key-%d", time.Now().UnixNano())
    75  		keyConf = shared.CurrentConfig.NewKey(argKeyName)
    76  	}
    77  	if argToken != "" {
    78  		tokenConf, err := shared.CurrentConfig.GetToken(argToken)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  		keyConf.SetToken(tokenConf)
    83  	}
    84  	if argLabel != "" {
    85  		keyConf.Label = argLabel
    86  		keyConf.ID = ""
    87  	}
    88  	return keyConf, nil
    89  }
    90  
    91  func selectOrGenerate() (key token.Key, err error) {
    92  	keyConf, err := newKeyConfig()
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	tok, err := openToken(keyConf.Token)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	key, err = tok.GetKey(argKeyName)
   101  	if err == nil {
   102  		fmt.Fprintln(os.Stderr, "Using existing key in token")
   103  		return key, nil
   104  	} else if _, ok := err.(sigerrors.KeyNotFoundError); !ok {
   105  		return nil, err
   106  	}
   107  	fmt.Fprintln(os.Stderr, "Generating a new key in token")
   108  	if argRsaBits != 0 {
   109  		return tok.Generate(argKeyName, token.KeyTypeRsa, argRsaBits)
   110  	} else if argEcdsaBits != 0 {
   111  		return tok.Generate(argKeyName, token.KeyTypeEcdsa, argEcdsaBits)
   112  	} else {
   113  		return nil, errors.New("No matching key exists, specify --generate-rsa or --generate-ecdsa to generate one")
   114  	}
   115  }
   116  
   117  func openToken(tokenName string) (token.Token, error) {
   118  	tok, ok := tokenMap[tokenName]
   119  	if ok {
   120  		return tok, nil
   121  	}
   122  	err := shared.InitConfig()
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	prompt := new(passprompt.PasswordPrompt)
   127  	tok, err = open.Token(shared.CurrentConfig, tokenName, prompt)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	if tokenMap == nil {
   132  		tokenMap = make(map[string]token.Token)
   133  	}
   134  	tokenMap[tokenName] = tok
   135  	return tok, nil
   136  }
   137  
   138  func openTokenByKey(keyName string) (token.Token, error) {
   139  	if keyName == "" {
   140  		return nil, errors.New("--key is a required parameter")
   141  	}
   142  	err := shared.InitConfig()
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  	keyConf, err := shared.CurrentConfig.GetKey(keyName)
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	tok, err := openToken(keyConf.Token)
   151  	if err != nil {
   152  		return nil, err
   153  	}
   154  	return tok, nil
   155  }
   156  
   157  func openKey(keyName string) (token.Key, error) {
   158  	tok, err := openTokenByKey(keyName)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  	key, err := tok.GetKey(keyName)
   163  	if err != nil {
   164  		tok.Close()
   165  		return nil, err
   166  	}
   167  	return key, err
   168  }
   169  
   170  func formatKeyID(keyID []byte) string {
   171  	chunks := make([]string, len(keyID))
   172  	for i, j := range keyID {
   173  		chunks[i] = fmt.Sprintf("%02x", j)
   174  	}
   175  	return strings.Join(chunks, ":")
   176  }
   177  

View as plain text