diff --git a/builtin/credential/cert/backend_test.go b/builtin/credential/cert/backend_test.go index 0840362f0bdc..fb9eb8ca5a31 100644 --- a/builtin/credential/cert/backend_test.go +++ b/builtin/credential/cert/backend_test.go @@ -9,7 +9,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" @@ -39,6 +38,7 @@ import ( vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/tokenutil" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" @@ -658,7 +658,7 @@ func TestBackend_NonCAExpiry(t *testing.T) { template.IPAddresses = []net.IP{parsedIP} // Private key for CA cert - caPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) + caPrivateKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } @@ -726,7 +726,7 @@ func TestBackend_NonCAExpiry(t *testing.T) { template.SerialNumber = big.NewInt(5678) template.KeyUsage = x509.KeyUsage(x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign) - issuedPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) + issuedPrivateKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } diff --git a/builtin/logical/database/credentials.go b/builtin/logical/database/credentials.go index 790dde05a35b..89e5b438a219 100644 --- a/builtin/logical/database/credentials.go +++ b/builtin/logical/database/credentials.go @@ -6,7 +6,6 @@ package database import ( "context" "crypto/rand" - "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" @@ -15,6 +14,8 @@ import ( "strings" "time" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" + "github.com/hashicorp/vault/helper/random" "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/helper/certutil" @@ -133,7 +134,7 @@ func (kg *rsaKeyGenerator) generate(r io.Reader) ([]byte, []byte, error) { return nil, nil, fmt.Errorf("invalid key_bits: %v", kg.KeyBits) } - key, err := rsa.GenerateKey(reader, keyBits) + key, err := cryptoutil.GenerateRSAKey(reader, keyBits) if err != nil { return nil, nil, err } diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index 3cdd73833eb5..5c38989f8f85 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -50,6 +50,7 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/teststorage" vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/testhelpers/schema" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" @@ -510,14 +511,14 @@ func generateURLSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s }, } - priv1024, _ := rsa.GenerateKey(rand.Reader, 1024) + priv1024, _ := cryptoutil.GenerateRSAKey(rand.Reader, 1024) csr1024, _ := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, priv1024) csrPem1024 := strings.TrimSpace(string(pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE REQUEST", Bytes: csr1024, }))) - priv2048, _ := rsa.GenerateKey(rand.Reader, 2048) + priv2048, _ := cryptoutil.GenerateRSAKey(rand.Reader, 2048) csr2048, _ := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, priv2048) csrPem2048 := strings.TrimSpace(string(pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE REQUEST", @@ -699,7 +700,7 @@ func generateCSR(t *testing.T, csrTemplate *x509.CertificateRequest, keyType str var err error switch keyType { case "rsa": - priv, err = rsa.GenerateKey(rand.Reader, keyBits) + priv, err = cryptoutil.GenerateRSAKey(rand.Reader, keyBits) case "ec": switch keyBits { case 224: @@ -1180,7 +1181,7 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep { case "rsa": privKey, ok = generatedRSAKeys[keyBits] if !ok { - privKey, _ = rsa.GenerateKey(rand.Reader, keyBits) + privKey, _ = cryptoutil.GenerateRSAKey(rand.Reader, keyBits) generatedRSAKeys[keyBits] = privKey } @@ -2164,7 +2165,7 @@ func runTestSignVerbatim(t *testing.T, keyType string) { } // create a CSR and key - key, err := rsa.GenerateKey(rand.Reader, 2048) + key, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } @@ -2735,7 +2736,7 @@ func TestBackend_SignSelfIssued(t *testing.T) { t.Fatal(err) } - key, err := rsa.GenerateKey(rand.Reader, 2048) + key, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } @@ -2879,7 +2880,7 @@ func TestBackend_SignSelfIssued_DifferentTypes(t *testing.T) { t.Fatal(err) } - key, err := rsa.GenerateKey(rand.Reader, 2048) + key, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } @@ -3834,7 +3835,7 @@ func setCerts() { } ecCACert = strings.TrimSpace(string(pem.EncodeToMemory(caCertPEMBlock))) - rak, err := rsa.GenerateKey(rand.Reader, 2048) + rak, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { panic(err) } diff --git a/builtin/logical/pki/ca_test.go b/builtin/logical/pki/ca_test.go index 4517604f8a0d..069c5777b9dd 100644 --- a/builtin/logical/pki/ca_test.go +++ b/builtin/logical/pki/ca_test.go @@ -9,7 +9,6 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/json" @@ -24,6 +23,7 @@ import ( "github.com/hashicorp/vault/api" vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" ) @@ -98,7 +98,7 @@ func TestBackend_CA_Steps(t *testing.T) { } ecCACert = strings.TrimSpace(string(pem.EncodeToMemory(caCertPEMBlock))) - rak, err := rsa.GenerateKey(rand.Reader, 2048) + rak, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { panic(err) } diff --git a/builtin/logical/pki/ca_util_test.go b/builtin/logical/pki/ca_util_test.go index d4ef64e68fe1..96d60e2c302d 100644 --- a/builtin/logical/pki/ca_util_test.go +++ b/builtin/logical/pki/ca_util_test.go @@ -9,14 +9,15 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "testing" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" + "github.com/hashicorp/vault/sdk/helper/certutil" ) func TestGetKeyTypeAndBitsFromPublicKeyForRole(t *testing.T) { - rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) + rsaKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatalf("error generating rsa key: %s", err) } diff --git a/builtin/logical/pki/path_acme_test.go b/builtin/logical/pki/path_acme_test.go index 493a601c985e..ac16c36cc871 100644 --- a/builtin/logical/pki/path_acme_test.go +++ b/builtin/logical/pki/path_acme_test.go @@ -32,6 +32,7 @@ import ( "github.com/hashicorp/vault/helper/testhelpers" vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" @@ -60,7 +61,7 @@ func TestAcmeBasicWorkflow(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { baseAcmeURL := "/v1/pki/" + tc.prefixUrl - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) @@ -592,7 +593,7 @@ func TestAcmeAccountsCrossingDirectoryPath(t *testing.T) { defer cluster.Cleanup() baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") testCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) @@ -628,7 +629,7 @@ func TestAcmeEabCrossingDirectoryPath(t *testing.T) { require.NoError(t, err) baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") testCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) @@ -838,7 +839,7 @@ func TestAcmeTruncatesToIssuerExpiry(t *testing.T) { require.NoError(t, err, "failed updating issuer name") baseAcmeURL := "/v1/pki/issuer/short-ca/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) @@ -910,7 +911,7 @@ func TestAcmeRoleExtKeyUsage(t *testing.T) { _, err := client.Logical().Write("pki/roles/"+roleName, roleOpt) baseAcmeURL := "/v1/pki/roles/" + roleName + "/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") require.NoError(t, err, "failed creating role test-role") @@ -1179,7 +1180,7 @@ func TestAcmeWithCsrIncludingBasicConstraintExtension(t *testing.T) { defer cancel() baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) @@ -1511,7 +1512,7 @@ func TestAcmeValidationError(t *testing.T) { defer cancel() baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) @@ -1619,7 +1620,7 @@ func TestAcmeRevocationAcrossAccounts(t *testing.T) { defer cancel() baseAcmeURL := "/v1/pki/acme/" - accountKey1, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey1, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient1 := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey1) @@ -1718,7 +1719,7 @@ func TestAcmeMaxTTL(t *testing.T) { require.NoError(t, err, "error configuring acme") // First Create Our Client - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, "/v1/pki/acme/", accountKey) @@ -1946,7 +1947,7 @@ func TestACMEClientRequestLimits(t *testing.T) { for _, tc := range cases { // First Create Our Client - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, "/v1/pki/acme/", accountKey) diff --git a/builtin/logical/pki/path_config_acme_test.go b/builtin/logical/pki/path_config_acme_test.go index 47ba1f817dec..cfc7eeb03f19 100644 --- a/builtin/logical/pki/path_config_acme_test.go +++ b/builtin/logical/pki/path_config_acme_test.go @@ -6,11 +6,11 @@ package pki import ( "context" "crypto/rand" - "crypto/rsa" "testing" "time" "github.com/hashicorp/vault/helper/constants" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/stretchr/testify/require" ) @@ -117,7 +117,7 @@ func TestAcmeConfig(t *testing.T) { require.NoError(t, err) baseAcmeURL := "/v1/pki/" + tc.prefixUrl - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) diff --git a/builtin/logical/pki/path_tidy_test.go b/builtin/logical/pki/path_tidy_test.go index f32bc880a59e..911e050dd003 100644 --- a/builtin/logical/pki/path_tidy_test.go +++ b/builtin/logical/pki/path_tidy_test.go @@ -8,7 +8,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/json" @@ -23,6 +22,7 @@ import ( "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/testhelpers" vaulthttp "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/testhelpers/schema" "github.com/hashicorp/vault/sdk/logical" @@ -916,7 +916,7 @@ func TestTidyAcmeWithBackdate(t *testing.T) { // Register an Account, do nothing with it baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) @@ -1073,7 +1073,7 @@ func TestTidyAcmeWithSafetyBuffer(t *testing.T) { // Register an Account, do nothing with it baseAcmeURL := "/v1/pki/acme/" - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa key") acmeClient := getAcmeClientForCluster(t, cluster, baseAcmeURL, accountKey) diff --git a/builtin/logical/pkiext/pkiext_binary/acme_test.go b/builtin/logical/pkiext/pkiext_binary/acme_test.go index f4a7be0c1d83..dfacff875779 100644 --- a/builtin/logical/pkiext/pkiext_binary/acme_test.go +++ b/builtin/logical/pkiext/pkiext_binary/acme_test.go @@ -8,7 +8,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" @@ -30,6 +29,7 @@ import ( "github.com/hashicorp/vault/helper/testhelpers" "github.com/hashicorp/vault/helper/testhelpers/corehelpers" "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" hDocker "github.com/hashicorp/vault/sdk/helper/docker" "github.com/stretchr/testify/require" "golang.org/x/crypto/acme" @@ -704,7 +704,7 @@ func doAcmeValidationWithGoLibrary(t *testing.T, directoryUrl string, acmeOrderI } httpClient := &http.Client{Transport: tr} - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa account key") logger.Trace("Using the following url for the ACME directory", "url", directoryUrl) acmeClient := &acme.Client{ @@ -957,7 +957,7 @@ func SubtestACMEStepDownNode(t *testing.T, cluster *VaultPkiCluster) { DNSNames: []string{hostname, hostname}, } - accountKey, err := rsa.GenerateKey(rand.Reader, 2048) + accountKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NoError(t, err, "failed creating rsa account key") acmeClient := &acme.Client{ diff --git a/builtin/logical/ssh/path_config_ca.go b/builtin/logical/ssh/path_config_ca.go index 6d003c0ae5c0..d0f0abae1309 100644 --- a/builtin/logical/ssh/path_config_ca.go +++ b/builtin/logical/ssh/path_config_ca.go @@ -10,7 +10,6 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "crypto/x509" "encoding/pem" "errors" @@ -19,6 +18,7 @@ import ( multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/logical" "github.com/mikesmitty/edkey" "golang.org/x/crypto/ssh" @@ -326,7 +326,7 @@ func generateSSHKeyPair(randomSource io.Reader, keyType string, keyBits int) (st return "", "", fmt.Errorf("refusing to generate weak %v key: %v bits < 2048 bits", keyType, keyBits) } - privateSeed, err := rsa.GenerateKey(randomSource, keyBits) + privateSeed, err := cryptoutil.GenerateRSAKey(randomSource, keyBits) if err != nil { return "", "", err } diff --git a/builtin/logical/ssh/util.go b/builtin/logical/ssh/util.go index 89980ada0132..5ba5633761e5 100644 --- a/builtin/logical/ssh/util.go +++ b/builtin/logical/ssh/util.go @@ -6,7 +6,6 @@ package ssh import ( "context" "crypto/rand" - "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" @@ -14,6 +13,8 @@ import ( "net" "strings" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" + "github.com/hashicorp/go-secure-stdlib/parseutil" "github.com/hashicorp/vault/sdk/logical" "golang.org/x/crypto/ssh" @@ -22,7 +23,7 @@ import ( // Creates a new RSA key pair with the given key length. The private key will be // of pem format and the public key will be of OpenSSH format. func generateRSAKeys(keyBits int) (publicKeyRsa string, privateKeyRsa string, err error) { - privateKey, err := rsa.GenerateKey(rand.Reader, keyBits) + privateKey, err := cryptoutil.GenerateRSAKey(rand.Reader, keyBits) if err != nil { return "", "", fmt.Errorf("error generating RSA key-pair: %w", err) } diff --git a/builtin/logical/transit/path_certificates_test.go b/builtin/logical/transit/path_certificates_test.go index 9a6305e7a048..b50916a07f81 100644 --- a/builtin/logical/transit/path_certificates_test.go +++ b/builtin/logical/transit/path_certificates_test.go @@ -6,7 +6,6 @@ package transit import ( "context" cryptoRand "crypto/rand" - "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" @@ -17,6 +16,7 @@ import ( "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/builtin/logical/pki" vaulthttp "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" "github.com/stretchr/testify/require" @@ -167,7 +167,7 @@ func testTransit_ImportCertChain(t *testing.T, apiClient *api.Client, keyType st require.NoError(t, err) // Setup a new CSR - privKey, err := rsa.GenerateKey(cryptoRand.Reader, 3072) + privKey, err := cryptoutil.GenerateRSAKey(cryptoRand.Reader, 3072) require.NoError(t, err) var csrTemplate x509.CertificateRequest diff --git a/builtin/logical/transit/path_import_test.go b/builtin/logical/transit/path_import_test.go index d26f5ff95f64..861f1fd67acc 100644 --- a/builtin/logical/transit/path_import_test.go +++ b/builtin/logical/transit/path_import_test.go @@ -20,6 +20,7 @@ import ( "testing" uuid "github.com/hashicorp/go-uuid" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/logical" "github.com/tink-crypto/tink-go/v2/kwp/subtle" ) @@ -162,7 +163,7 @@ func TestTransit_Import(t *testing.T) { t.Run( "import into a key fails before wrapping key is read", func(t *testing.T) { - fakeWrappingKey, err := rsa.GenerateKey(rand.Reader, 4096) + fakeWrappingKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 4096) if err != nil { t.Fatalf("failed to generate fake wrapping key: %s", err) } @@ -502,7 +503,7 @@ func TestTransit_ImportVersion(t *testing.T) { t.Run( "import into a key version fails before wrapping key is read", func(t *testing.T) { - fakeWrappingKey, err := rsa.GenerateKey(rand.Reader, 4096) + fakeWrappingKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 4096) if err != nil { t.Fatalf("failed to generate fake wrapping key: %s", err) } @@ -1027,11 +1028,11 @@ func generateKey(keyType string) (interface{}, error) { case "ecdsa-p521": return ecdsa.GenerateKey(elliptic.P521(), rand.Reader) case "rsa-2048": - return rsa.GenerateKey(rand.Reader, 2048) + return cryptoutil.GenerateRSAKey(rand.Reader, 2048) case "rsa-3072": - return rsa.GenerateKey(rand.Reader, 3072) + return cryptoutil.GenerateRSAKey(rand.Reader, 3072) case "rsa-4096": - return rsa.GenerateKey(rand.Reader, 4096) + return cryptoutil.GenerateRSAKey(rand.Reader, 4096) default: return nil, fmt.Errorf("failed to generate unsupported key type: %s", keyType) } diff --git a/changelog/29020.txt b/changelog/29020.txt new file mode 100644 index 000000000000..928e61d265f0 --- /dev/null +++ b/changelog/29020.txt @@ -0,0 +1,5 @@ +```release-note: improvement +sdk/helper: utitilize a randomly seeded cryptographic determinstic random bit generator for +RSA key generation when using slow random sources, speeding key generation +considerably. +``` diff --git a/command/transit_import_key_test.go b/command/transit_import_key_test.go index 847ab59ff78f..5994f91e3372 100644 --- a/command/transit_import_key_test.go +++ b/command/transit_import_key_test.go @@ -7,13 +7,13 @@ import ( "bytes" "context" "crypto/rand" - "crypto/rsa" "crypto/x509" "encoding/base64" "testing" "time" "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/stretchr/testify/require" ) @@ -171,7 +171,7 @@ func execTransitImport(t *testing.T, client *api.Client, method string, path str func generateKeys(t *testing.T) (rsa1 []byte, rsa2 []byte, aes128 []byte, aes256 []byte) { t.Helper() - priv1, err := rsa.GenerateKey(rand.Reader, 2048) + priv1, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NotNil(t, priv1, "failed generating RSA 1 key") require.NoError(t, err, "failed generating RSA 1 key") @@ -179,7 +179,7 @@ func generateKeys(t *testing.T) (rsa1 []byte, rsa2 []byte, aes128 []byte, aes256 require.NotNil(t, rsa1, "failed marshaling RSA 1 key") require.NoError(t, err, "failed marshaling RSA 1 key") - priv2, err := rsa.GenerateKey(rand.Reader, 2048) + priv2, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) require.NotNil(t, priv2, "failed generating RSA 2 key") require.NoError(t, err, "failed generating RSA 2 key") diff --git a/go.mod b/go.mod index a56404602521..9b998cd305a3 100644 --- a/go.mod +++ b/go.mod @@ -100,6 +100,7 @@ require ( github.com/hashicorp/go-rootcerts v1.0.2 github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 + github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0 github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1 github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.2 github.com/hashicorp/go-secure-stdlib/mlock v0.1.3 @@ -237,6 +238,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-viper/mapstructure/v2 v2.1.0 // indirect + github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 // indirect github.com/hashicorp/go-secure-stdlib/httputil v0.1.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect diff --git a/go.sum b/go.sum index d83f25ac44fb..8c38651d7f1b 100644 --- a/go.sum +++ b/go.sum @@ -1414,6 +1414,8 @@ github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39 github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 h1:kBoJV4Xl5FLtBfnBjDvBxeNSy2IRITSGs73HQsFUEjY= +github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6/go.mod h1:y+HSOcOGB48PkUxNyLAiCiY6rEENu+E+Ss4LG8QHwf4= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= @@ -1461,6 +1463,8 @@ github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 h1:I8bynUKMh9I7JdwtW9voJ0xm github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0/go.mod h1:oKHSQs4ivIfZ3fbXGQOop1XuDfdSb8RIsWTGaAanSfg= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= +github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0 h1:4B46+S65WqQUlp0rX2F7TX6/p0HmUZsDD+cVzFTwztw= +github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0/go.mod h1:hH8rgXHh9fPSDPerG6WzABHsHF+9ZpLhRI1LPk4JZ8c= github.com/hashicorp/go-secure-stdlib/fileutil v0.1.0 h1:f2mwVgMJjXuX/+eWD6ZW30+oIRgCofL+XMWknFkB1WM= github.com/hashicorp/go-secure-stdlib/fileutil v0.1.0/go.mod h1:uwcr2oga9pN5+OkHZyTN5MDk3+1YHOuMukhpnPaQAoI= github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1 h1:9um9R8i0+HbRHS9d64kdvWR0/LJvo12sIonvR9zr1+U= diff --git a/helper/testhelpers/certhelpers/cert_helpers.go b/helper/testhelpers/certhelpers/cert_helpers.go index d9c89735c618..e0b31fcc0e5b 100644 --- a/helper/testhelpers/certhelpers/cert_helpers.go +++ b/helper/testhelpers/certhelpers/cert_helpers.go @@ -18,6 +18,8 @@ import ( "strings" "testing" "time" + + "github.com/hashicorp/vault/sdk/helper/cryptoutil" ) type CertBuilder struct { @@ -166,7 +168,7 @@ type KeyWrapper struct { func NewPrivateKey(t *testing.T) (key KeyWrapper) { t.Helper() - privKey, err := rsa.GenerateKey(rand.Reader, 2048) + privKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatalf("Unable to generate key for cert: %s", err) } diff --git a/plugins/database/mongodb/cert_helpers_test.go b/plugins/database/mongodb/cert_helpers_test.go index 3a8f3afcb84f..9082055c643c 100644 --- a/plugins/database/mongodb/cert_helpers_test.go +++ b/plugins/database/mongodb/cert_helpers_test.go @@ -17,6 +17,8 @@ import ( "strings" "testing" "time" + + "github.com/hashicorp/vault/sdk/helper/cryptoutil" ) type certBuilder struct { @@ -154,7 +156,7 @@ type keyWrapper struct { func newPrivateKey(t *testing.T) (key keyWrapper) { t.Helper() - privKey, err := rsa.GenerateKey(rand.Reader, 2048) + privKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatalf("Unable to generate key for cert: %s", err) } diff --git a/sdk/go.mod b/sdk/go.mod index 68f13ce14ea7..8d306d850a4e 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -26,6 +26,7 @@ require ( github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 + github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0 github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 github.com/hashicorp/go-secure-stdlib/password v0.1.1 @@ -58,6 +59,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/go-jose/go-jose/v4 v4.0.1 // indirect + github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect diff --git a/sdk/go.sum b/sdk/go.sum index 55705f4931ac..b226fc928814 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -237,6 +237,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 h1:kBoJV4Xl5FLtBfnBjDvBxeNSy2IRITSGs73HQsFUEjY= +github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6/go.mod h1:y+HSOcOGB48PkUxNyLAiCiY6rEENu+E+Ss4LG8QHwf4= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -255,6 +257,8 @@ github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5O github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= +github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0 h1:4B46+S65WqQUlp0rX2F7TX6/p0HmUZsDD+cVzFTwztw= +github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.0/go.mod h1:hH8rgXHh9fPSDPerG6WzABHsHF+9ZpLhRI1LPk4JZ8c= github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 h1:p4AKXPPS24tO8Wc8i1gLvSKdmkiSY5xuju57czJ/IJQ= github.com/hashicorp/go-secure-stdlib/mlock v0.1.2/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc= diff --git a/sdk/helper/certutil/certutil_test.go b/sdk/helper/certutil/certutil_test.go index c872454f155d..5151b37cf6e8 100644 --- a/sdk/helper/certutil/certutil_test.go +++ b/sdk/helper/certutil/certutil_test.go @@ -26,6 +26,7 @@ import ( "time" "github.com/fatih/structs" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" ) // Tests converting back and forth between a CertBundle and a ParsedCertBundle. @@ -465,7 +466,7 @@ vitin0L6nprauWkKO38XgM4T75qKZpqtiOcT } func TestGetPublicKeySize(t *testing.T) { - rsa, err := rsa.GenerateKey(rand.Reader, 3072) + rsa, err := cryptoutil.GenerateRSAKey(rand.Reader, 3072) if err != nil { t.Fatal(err) } @@ -735,7 +736,7 @@ func setCerts() { // RSA generation { - key, err := rsa.GenerateKey(rand.Reader, 2048) + key, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { panic(err) } @@ -864,7 +865,7 @@ func setCerts() { func TestComparePublicKeysAndType(t *testing.T) { rsa1 := genRsaKey(t).Public() - rsa2 := genRsaKey(t).Public() + rsa := genRsaKey(t).Public() eddsa1 := genEdDSA(t).Public() eddsa2 := genEdDSA(t).Public() ed25519_1, _ := genEd25519Key(t) @@ -881,7 +882,7 @@ func TestComparePublicKeysAndType(t *testing.T) { wantErr bool }{ {name: "RSA_Equal", args: args{key1Iface: rsa1, key2Iface: rsa1}, want: true, wantErr: false}, - {name: "RSA_NotEqual", args: args{key1Iface: rsa1, key2Iface: rsa2}, want: false, wantErr: false}, + {name: "RSA_NotEqual", args: args{key1Iface: rsa1, key2Iface: rsa}, want: false, wantErr: false}, {name: "EDDSA_Equal", args: args{key1Iface: eddsa1, key2Iface: eddsa1}, want: true, wantErr: false}, {name: "EDDSA_NotEqual", args: args{key1Iface: eddsa1, key2Iface: eddsa2}, want: false, wantErr: false}, {name: "ED25519_Equal", args: args{key1Iface: ed25519_1, key2Iface: ed25519_1}, want: true, wantErr: false}, @@ -1106,7 +1107,7 @@ func TestIgnoreCSRSigning(t *testing.T) { } func genRsaKey(t *testing.T) *rsa.PrivateKey { - key, err := rsa.GenerateKey(rand.Reader, 2048) + key, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } diff --git a/sdk/helper/certutil/helpers.go b/sdk/helper/certutil/helpers.go index 1c673b058acd..8a03b7cedf7e 100644 --- a/sdk/helper/certutil/helpers.go +++ b/sdk/helper/certutil/helpers.go @@ -29,6 +29,8 @@ import ( "strings" "time" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" + "github.com/hashicorp/errwrap" "github.com/hashicorp/vault/sdk/helper/errutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" @@ -368,7 +370,7 @@ func generatePrivateKey(keyType string, keyBits int, container ParsedPrivateKeyC return errutil.InternalError{Err: fmt.Sprintf("insecure bit length for RSA private key: %d", keyBits)} } privateKeyType = RSAPrivateKey - privateKey, err = rsa.GenerateKey(randReader, keyBits) + privateKey, err = cryptoutil.GenerateRSAKey(randReader, keyBits) if err != nil { return errutil.InternalError{Err: fmt.Sprintf("error generating RSA private key: %v", err)} } diff --git a/sdk/helper/certutil/types_test.go b/sdk/helper/certutil/types_test.go index 2cf383afaa02..02288d17d77a 100644 --- a/sdk/helper/certutil/types_test.go +++ b/sdk/helper/certutil/types_test.go @@ -9,12 +9,13 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "testing" + + "github.com/hashicorp/vault/sdk/helper/cryptoutil" ) func TestGetPrivateKeyTypeFromPublicKey(t *testing.T) { - rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) + rsaKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { t.Fatalf("error generating rsa key: %s", err) } diff --git a/sdk/helper/cryptoutil/rsa.go b/sdk/helper/cryptoutil/rsa.go new file mode 100644 index 000000000000..5c6790ba9c9a --- /dev/null +++ b/sdk/helper/cryptoutil/rsa.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cryptoutil + +import ( + "crypto/rsa" + "io" + "os" + + "github.com/hashicorp/go-secure-stdlib/cryptoutil" + "github.com/hashicorp/vault/sdk/helper/parseutil" +) + +var disabled bool + +func init() { + s := os.Getenv("VAULT_DISABLE_RSA_DRBG") + var err error + disabled, err = parseutil.ParseBool(s) + if err != nil { + // Assume it's a typo and disable + disabled = true + } +} + +// Uses go-secure-stdlib's GenerateRSAKey routine conditionally. This exists to be able to disable the feature +// via an ENV var in a pinch +func GenerateRSAKey(randomSource io.Reader, bits int) (*rsa.PrivateKey, error) { + if disabled { + return rsa.GenerateKey(randomSource, bits) + } + return cryptoutil.GenerateRSAKey(randomSource, bits) +} diff --git a/sdk/helper/keysutil/policy.go b/sdk/helper/keysutil/policy.go index 138918eb8cb3..3e4be8b1cd71 100644 --- a/sdk/helper/keysutil/policy.go +++ b/sdk/helper/keysutil/policy.go @@ -35,6 +35,7 @@ import ( "github.com/hashicorp/errwrap" "github.com/hashicorp/go-uuid" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/errutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/kdf" @@ -1825,7 +1826,7 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) { bitSize = 4096 } - entry.RSAKey, err = rsa.GenerateKey(randReader, bitSize) + entry.RSAKey, err = cryptoutil.GenerateRSAKey(randReader, bitSize) if err != nil { return err } diff --git a/sdk/helper/keysutil/policy_test.go b/sdk/helper/keysutil/policy_test.go index 5e3ce1ee9d99..dd125e0b88c1 100644 --- a/sdk/helper/keysutil/policy_test.go +++ b/sdk/helper/keysutil/policy_test.go @@ -22,6 +22,7 @@ import ( "testing" "time" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/errutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/logical" @@ -810,7 +811,7 @@ func Test_Import(t *testing.T) { func generateTestKeys() (map[KeyType][]byte, error) { keyMap := make(map[KeyType][]byte) - rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) + rsaKey, err := cryptoutil.GenerateRSAKey(rand.Reader, 2048) if err != nil { return nil, err } @@ -820,7 +821,7 @@ func generateTestKeys() (map[KeyType][]byte, error) { } keyMap[KeyType_RSA2048] = rsaKeyBytes - rsaKey, err = rsa.GenerateKey(rand.Reader, 3072) + rsaKey, err = cryptoutil.GenerateRSAKey(rand.Reader, 3072) if err != nil { return nil, err } @@ -830,7 +831,7 @@ func generateTestKeys() (map[KeyType][]byte, error) { } keyMap[KeyType_RSA3072] = rsaKeyBytes - rsaKey, err = rsa.GenerateKey(rand.Reader, 4096) + rsaKey, err = cryptoutil.GenerateRSAKey(rand.Reader, 4096) if err != nil { return nil, err } diff --git a/vault/identity_store_oidc.go b/vault/identity_store_oidc.go index 5b34631f2d7d..a5c487456b2e 100644 --- a/vault/identity_store_oidc.go +++ b/vault/identity_store_oidc.go @@ -8,7 +8,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - "crypto/rsa" "encoding/base64" "encoding/json" "errors" @@ -30,6 +29,7 @@ import ( "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" + "github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/identitytpl" "github.com/hashicorp/vault/sdk/logical" "github.com/patrickmn/go-cache" @@ -1762,7 +1762,7 @@ func generateKeys(algorithm string) (*jose.JSONWebKey, error) { switch algorithm { case "RS256", "RS384", "RS512": // 2048 bits is recommended by RSA Laboratories as a minimum post 2015 - if key, err = rsa.GenerateKey(rand.Reader, 2048); err != nil { + if key, err = cryptoutil.GenerateRSAKey(rand.Reader, 2048); err != nil { return nil, err } case "ES256", "ES384", "ES512":