github.com/hashicorp/vault/sdk@v0.11.0/helper/roottoken/otp.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package roottoken
     5  
     6  import (
     7  	"crypto/rand"
     8  	"encoding/base64"
     9  	"fmt"
    10  
    11  	"github.com/hashicorp/go-secure-stdlib/base62"
    12  )
    13  
    14  // DefaultBase64EncodedOTPLength is the number of characters that will be randomly generated
    15  // before the Base64 encoding process takes place.
    16  const defaultBase64EncodedOTPLength = 16
    17  
    18  // GenerateOTP generates a random token and encodes it as a Base64 or as a Base62 encoded string.
    19  // Returns 0 if the generation completed without any error, 2 otherwise, along with the error.
    20  func GenerateOTP(otpLength int) (string, error) {
    21  	switch otpLength {
    22  	case 0:
    23  		// This is the fallback case
    24  		buf := make([]byte, defaultBase64EncodedOTPLength)
    25  		readLen, err := rand.Read(buf)
    26  		if err != nil {
    27  			return "", fmt.Errorf("error reading random bytes: %s", err)
    28  		}
    29  
    30  		if readLen != defaultBase64EncodedOTPLength {
    31  			return "", fmt.Errorf("read %d bytes when we should have read 16", readLen)
    32  		}
    33  
    34  		return base64.StdEncoding.EncodeToString(buf), nil
    35  	default:
    36  		otp, err := base62.Random(otpLength)
    37  		if err != nil {
    38  			return "", fmt.Errorf("error reading random bytes: %w", err)
    39  		}
    40  
    41  		return otp, nil
    42  	}
    43  }