Skip to content

Commit 5455c18

Browse files
authored
Merge pull request #13 from cruxstack/dev
feat: convert okta private key to the expected type
2 parents 7ea3a97 + 3f5aaaa commit 5455c18

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

internal/okta/client.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ package okta
44

55
import (
66
"context"
7+
"crypto/rsa"
78
"crypto/tls"
89
"crypto/x509"
10+
"encoding/pem"
911
"fmt"
1012
"net/http"
1113

@@ -19,6 +21,45 @@ import (
1921
// these scopes are necessary for group sync functionality.
2022
var DefaultScopes = []string{"okta.groups.read", "okta.users.read"}
2123

24+
// convertToPKCS1 converts a PEM-encoded private key to PKCS#1 format if needed.
25+
// the Okta SDK requires PKCS#1 format (BEGIN RSA PRIVATE KEY), but Okta's
26+
// console generates PKCS#8 keys (BEGIN PRIVATE KEY). this function detects the
27+
// format and converts PKCS#8 to PKCS#1 automatically.
28+
func convertToPKCS1(keyPEM []byte) ([]byte, error) {
29+
block, _ := pem.Decode(keyPEM)
30+
if block == nil {
31+
return nil, errors.New("failed to decode pem block from private key")
32+
}
33+
34+
// already in PKCS#1 format
35+
if block.Type == "RSA PRIVATE KEY" {
36+
return keyPEM, nil
37+
}
38+
39+
// convert PKCS#8 to PKCS#1
40+
if block.Type == "PRIVATE KEY" {
41+
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
42+
if err != nil {
43+
return nil, errors.Wrap(err, "failed to parse pkcs#8 private key")
44+
}
45+
46+
rsaKey, ok := key.(*rsa.PrivateKey)
47+
if !ok {
48+
return nil, errors.New("private key is not an rsa key")
49+
}
50+
51+
pkcs1Bytes := x509.MarshalPKCS1PrivateKey(rsaKey)
52+
pkcs1PEM := pem.EncodeToMemory(&pem.Block{
53+
Type: "RSA PRIVATE KEY",
54+
Bytes: pkcs1Bytes,
55+
})
56+
57+
return pkcs1PEM, nil
58+
}
59+
60+
return nil, errors.Newf("unsupported private key type: %s", block.Type)
61+
}
62+
2263
// Client wraps the Okta SDK client with custom configuration.
2364
type Client struct {
2465
client *okta.Client
@@ -54,11 +95,16 @@ func NewClientWithContext(ctx context.Context, cfg *ClientConfig) (*Client, erro
5495
orgURL = fmt.Sprintf("https://%s", cfg.Domain)
5596
}
5697

98+
privateKey, err := convertToPKCS1(cfg.PrivateKey)
99+
if err != nil {
100+
return nil, errors.Wrap(err, "failed to convert private key")
101+
}
102+
57103
opts := []okta.ConfigSetter{
58104
okta.WithOrgUrl(orgURL),
59105
okta.WithAuthorizationMode("PrivateKey"),
60106
okta.WithClientId(cfg.ClientID),
61-
okta.WithPrivateKey(string(cfg.PrivateKey)),
107+
okta.WithPrivateKey(string(privateKey)),
62108
}
63109

64110
if len(cfg.Scopes) > 0 {

0 commit comments

Comments
 (0)