Skip to content

Fix creation of JKS wallet for Oracle.#47212

Merged
Tener merged 3 commits intomasterfrom
tener/oracle-unwrap-pk
Oct 8, 2024
Merged

Fix creation of JKS wallet for Oracle.#47212
Tener merged 3 commits intomasterfrom
tener/oracle-unwrap-pk

Conversation

@Tener
Copy link
Copy Markdown
Contributor

@Tener Tener commented Oct 4, 2024

Unwrap *keys.PrivateKey to fetch inner signer that satisfies x509.MarshalPKCS8PrivateKey expectations. This change allows passing keys.PrivateKey to createJKSWallet. The updated function will correctly marshal the private key for Oracle's JKS wallet creation.

Unwrap *keys.PrivateKey to fetch inner signer that satisfies `x509.MarshalPKCS8PrivateKey` expectations. This change allows passing keys.PrivateKey to createJKSWallet. The updated function will correctly marshal the private key for Oracle's JKS wallet creation.
@Tener Tener requested a review from nklaassen October 4, 2024 17:58
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Oct 4, 2024

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@github-actions github-actions Bot requested review from atburke and tigrato October 4, 2024 17:59
@Tener
Copy link
Copy Markdown
Contributor Author

Tener commented Oct 4, 2024

This is a result of tsh db connect to Oracle db without the fix:

ERROR REPORT:
Original Error: *errors.errorString x509: unknown key type while marshaling PKCS#8: *keys.PrivateKey
Stack Trace:
	github.com/gravitational/teleport/lib/client/db/oracle/oracle.go:91 github.com/gravitational/teleport/lib/client/db/oracle.createJKSWallet
	github.com/gravitational/teleport/lib/client/db/oracle/oracle.go:77 github.com/gravitational/teleport/lib/client/db/oracle.createClientWallet
	github.com/gravitational/teleport/lib/client/db/oracle/oracle.go:60 github.com/gravitational/teleport/lib/client/db/oracle.GenerateClientConfiguration
	github.com/gravitational/teleport/tool/tsh/common/db.go:338 github.com/gravitational/teleport/tool/tsh/common.databaseLogin
	github.com/gravitational/teleport/tool/tsh/common/db.go:1366 github.com/gravitational/teleport/tool/tsh/common.maybeDatabaseLogin
	github.com/gravitational/teleport/tool/tsh/common/db.go:765 github.com/gravitational/teleport/tool/tsh/common.onDatabaseConnect
	github.com/gravitational/teleport/tool/tsh/common/tsh.go:1512 github.com/gravitational/teleport/tool/tsh/common.Run
	github.com/gravitational/teleport/tool/tsh/common/tsh.go:614 github.com/gravitational/teleport/tool/tsh/common.Main
	github.com/gravitational/teleport/tool/tsh/main.go:26 main.main
	runtime/proc.go:272 runtime.main
	runtime/asm_arm64.s:1223 runtime.goexit
User Message: x509: unknown key type while marshaling PKCS#8: *keys.PrivateKey

@Tener Tener requested a review from greedy52 October 4, 2024 18:03
@Tener
Copy link
Copy Markdown
Contributor Author

Tener commented Oct 4, 2024

No need for backports, v16 doesn't seem affected. Pretty sure this is due to recent reshuffling of various crypto bits.

@Tener Tener added the no-changelog Indicates that a PR does not require a changelog entry label Oct 4, 2024
Copy link
Copy Markdown
Contributor

@greedy52 greedy52 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread lib/client/db/oracle/oracle.go Outdated
Comment on lines +90 to +93
// unwrap *keys.PrivateKey if necessary.
if pk, ok := signer.(*keys.PrivateKey); ok {
signer = pk.Signer
}
Copy link
Copy Markdown
Contributor

@greedy52 greedy52 Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

super nit. since api/utils/key is imported, could we change signer crypto.Signer, to signer *keys.PrivateKey in this file? maybe move x509.MarshalPKCS8PrivateKey to keys.PrivateKey too as a helper

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, there are quite a few options here if we want to refactor this further.

@nklaassen any ideas here? Looks like these changes are due to:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah my bad, sorry about this. I hate how all these crypto libs accept a key as any type and throw type safety out the window.

I think I would just do this instead of the type assertion, but that's harder to test against :)

diff --git a/tool/tsh/common/db.go b/tool/tsh/common/db.go
index cf107f20dc..f8c125b378 100644
--- a/tool/tsh/common/db.go
+++ b/tool/tsh/common/db.go
@@ -335,7 +335,7 @@ func databaseLogin(cf *CLIConf, tc *client.TeleportClient, dbInfo *databaseInfo)
                if err := generateDBLocalProxyCert(keyRing.TLSPrivateKey, profile); err != nil {
                        return trace.Wrap(err)
                }
-               err = oracle.GenerateClientConfiguration(keyRing.TLSPrivateKey, dbInfo.RouteToDatabase, profile)
+               err = oracle.GenerateClientConfiguration(keyRing.TLSPrivateKey.Signer, dbInfo.RouteToDatabase, profile)
                if err != nil {
                        return trace.Wrap(err)
                }

I think the right solution would be to never embed crypto.Signer and un-embed it from keys.PrivateKey, just because of how many places accept a crypto.Signer and then try to assert it to one of the standard library types, but I'm not sure I have time for that right now, it breaks a lot

For now maybe we could add a function api/utils/keys.MarshalSoftwarePrivateKeyPKCS8DER

func MarshalSoftwarePrivateKeyPKCS8DER(signer crypto.Signer) ([]byte, error) {
     switch k := signer.(type) {
     case *PrivateKey:
          return MarshalSoftwarePrivateKeyPKCS8Der(k.Signer)
     case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
          return x509.MarshalPKCS8PrivateKey(k)
     default:
         return nil, trace.BadParameter("unsupported key type: %T", signer)
     }
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I've added MarshalSoftwarePrivateKeyPKCS8DER now. PTAL.

Comment thread lib/client/db/oracle/oracle.go Outdated
Comment on lines +90 to +93
// unwrap *keys.PrivateKey if necessary.
if pk, ok := signer.(*keys.PrivateKey); ok {
signer = pk.Signer
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah my bad, sorry about this. I hate how all these crypto libs accept a key as any type and throw type safety out the window.

I think I would just do this instead of the type assertion, but that's harder to test against :)

diff --git a/tool/tsh/common/db.go b/tool/tsh/common/db.go
index cf107f20dc..f8c125b378 100644
--- a/tool/tsh/common/db.go
+++ b/tool/tsh/common/db.go
@@ -335,7 +335,7 @@ func databaseLogin(cf *CLIConf, tc *client.TeleportClient, dbInfo *databaseInfo)
                if err := generateDBLocalProxyCert(keyRing.TLSPrivateKey, profile); err != nil {
                        return trace.Wrap(err)
                }
-               err = oracle.GenerateClientConfiguration(keyRing.TLSPrivateKey, dbInfo.RouteToDatabase, profile)
+               err = oracle.GenerateClientConfiguration(keyRing.TLSPrivateKey.Signer, dbInfo.RouteToDatabase, profile)
                if err != nil {
                        return trace.Wrap(err)
                }

I think the right solution would be to never embed crypto.Signer and un-embed it from keys.PrivateKey, just because of how many places accept a crypto.Signer and then try to assert it to one of the standard library types, but I'm not sure I have time for that right now, it breaks a lot

For now maybe we could add a function api/utils/keys.MarshalSoftwarePrivateKeyPKCS8DER

func MarshalSoftwarePrivateKeyPKCS8DER(signer crypto.Signer) ([]byte, error) {
     switch k := signer.(type) {
     case *PrivateKey:
          return MarshalSoftwarePrivateKeyPKCS8Der(k.Signer)
     case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
          return x509.MarshalPKCS8PrivateKey(k)
     default:
         return nil, trace.BadParameter("unsupported key type: %T", signer)
     }
}

Comment thread lib/client/db/oracle/oracle_test.go Outdated
@Tener Tener requested a review from nklaassen October 7, 2024 07:16
Co-authored-by: Nic Klaassen <nic@goteleport.com>
@Tener Tener added this pull request to the merge queue Oct 7, 2024
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 7, 2024
@Tener Tener added this pull request to the merge queue Oct 8, 2024
Merged via the queue into master with commit cb2f54c Oct 8, 2024
@Tener Tener deleted the tener/oracle-unwrap-pk branch October 8, 2024 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/sm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants