github.com/zntrio/harp/v2@v2.0.9/pkg/sdk/security/crypto/asymmetric.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package crypto
    19  
    20  import (
    21  	"crypto/ecdsa"
    22  	"crypto/ed25519"
    23  	"crypto/elliptic"
    24  	"crypto/rand"
    25  	"crypto/rsa"
    26  	"fmt"
    27  
    28  	"github.com/pkg/errors"
    29  
    30  	"github.com/zntrio/harp/v2/build/fips"
    31  
    32  	"golang.org/x/crypto/nacl/box"
    33  )
    34  
    35  // Keypair generates crypto keys according to given key type.
    36  func Keypair(keyType string) (interface{}, error) {
    37  	// Generate crypto materials
    38  	pub, priv, err := generateKeyPair(keyType)
    39  	if err != nil {
    40  		return nil, fmt.Errorf("unable to generate a %q key pair: %w", keyType, err)
    41  	}
    42  
    43  	// No error
    44  	return struct {
    45  		Private interface{}
    46  		Public  interface{}
    47  	}{
    48  		Private: priv,
    49  		Public:  pub,
    50  	}, nil
    51  }
    52  
    53  // -----------------------------------------------------------------------------
    54  
    55  //nolint:gocyclo // To refactor
    56  func generateKeyPair(keyType string) (publicKey, privateKey interface{}, err error) {
    57  	switch keyType {
    58  	case "rsa", "rsa:normal", "rsa:2048":
    59  		key, err := rsa.GenerateKey(rand.Reader, 2048)
    60  		if err != nil {
    61  			return nil, nil, fmt.Errorf("unable to generate rsa-2048 key: %w", err)
    62  		}
    63  		pub := key.Public()
    64  		return pub, key, nil
    65  	case "rsa:strong", "rsa:4096":
    66  		key, err := rsa.GenerateKey(rand.Reader, 4096)
    67  		if err != nil {
    68  			return nil, nil, fmt.Errorf("unable to generate rsa-4096 key: %w", err)
    69  		}
    70  		pub := key.Public()
    71  		return pub, key, nil
    72  	case "ec", "ec:normal", "ec:p256":
    73  		key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    74  		if err != nil {
    75  			return nil, nil, fmt.Errorf("unable to generate ec-p256 key: %w", err)
    76  		}
    77  		pub := key.Public()
    78  		return pub, key, nil
    79  	case "ec:high", "ec:p384":
    80  		key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
    81  		if err != nil {
    82  			return nil, nil, fmt.Errorf("unable to generate ec-p384 key: %w", err)
    83  		}
    84  		pub := key.Public()
    85  		return pub, key, nil
    86  	case "ec:strong", "ec:p521":
    87  		key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
    88  		if err != nil {
    89  			return nil, nil, fmt.Errorf("unable to generate ec-p521 key: %w", err)
    90  		}
    91  		pub := key.Public()
    92  		return pub, key, nil
    93  	case "ssh", "ed25519":
    94  		if fips.Enabled() {
    95  			return nil, nil, errors.New("ed25519 key processing is disabled in FIPS Mode")
    96  		}
    97  		pub, priv, err := ed25519.GenerateKey(rand.Reader)
    98  		if err != nil {
    99  			return nil, nil, fmt.Errorf("unable to generate ed25519 key: %w", err)
   100  		}
   101  		return pub, priv, nil
   102  	case "naclbox", "x25519":
   103  		if fips.Enabled() {
   104  			return nil, nil, errors.New("x25519 key processing is disabled in FIPS Mode")
   105  		}
   106  		pub, priv, err := box.GenerateKey(rand.Reader)
   107  		if err != nil {
   108  			return nil, nil, fmt.Errorf("unable to generate naclbox key: %w", err)
   109  		}
   110  		return pub, priv, nil
   111  	default:
   112  		return nil, nil, fmt.Errorf("invalid keytype (%s) [(rsa, rsa:normal, rsa:2048), (rsa:strong, rsa:4096), (ec, ec:normal, ec:p256), (ec:high, ec:p384), (ec:strong, ec:p521), (ssh, ed25519), (naclbox, x25519)]", keyType)
   113  	}
   114  }