Skip to content

Commit ed4ccff

Browse files
committed
Address review: restore OIDC pubkey file loading and well-known config
- oidc_service.go: revert to loading public key from PublicKeyPath (parse PEM/PKIX) instead of deriving from privateKey.PublicKey. Lets operators supply their own public key; more predictable behavior. - well_known_controller.go: restore RequestParameterSupported=true and RequestObjectSigningAlgValuesSupported=["none"]. #864 is a false positive — frontend parses the JWT. - well_known_controller_test.go: restore matching expected values.
1 parent dd42743 commit ed4ccff

3 files changed

Lines changed: 49 additions & 12 deletions

File tree

internal/controller/well_known_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ func (controller *WellKnownController) OpenIDConnectConfiguration(c *gin.Context
6565
TokenEndpointAuthMethodsSupported: []string{"client_secret_basic", "client_secret_post"},
6666
ClaimsSupported: []string{"sub", "updated_at", "name", "preferred_username", "email", "email_verified", "groups", "phone_number", "phone_number_verified", "address", "given_name", "family_name", "middle_name", "nickname", "profile", "picture", "website", "gender", "birthdate", "zoneinfo", "locale"},
6767
ServiceDocumentation: "https://tinyauth.app/docs/guides/oidc",
68-
RequestParameterSupported: false,
68+
RequestParameterSupported: true,
69+
RequestObjectSigningAlgValuesSupported: []string{"none"},
6970
})
7071
}
7172

internal/controller/well_known_controller_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ func TestWellKnownController(t *testing.T) {
5757
TokenEndpointAuthMethodsSupported: []string{"client_secret_basic", "client_secret_post"},
5858
ClaimsSupported: []string{"sub", "updated_at", "name", "preferred_username", "email", "email_verified", "groups", "phone_number", "phone_number_verified", "address", "given_name", "family_name", "middle_name", "nickname", "profile", "picture", "website", "gender", "birthdate", "zoneinfo", "locale"},
5959
ServiceDocumentation: "https://tinyauth.app/docs/guides/oidc",
60-
RequestParameterSupported: false,
60+
RequestParameterSupported: true,
61+
RequestObjectSigningAlgValuesSupported: []string{"none"},
6162
}
6263

6364
assert.Equal(t, expected, res)

internal/service/oidc_service.go

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package service
22

33
import (
44
"context"
5+
"crypto"
56
"crypto/rand"
67
"crypto/rsa"
78
"crypto/sha256"
@@ -120,6 +121,7 @@ type OIDCService struct {
120121

121122
clients map[string]model.OIDCClientConfig
122123
privateKey *rsa.PrivateKey
124+
publicKey crypto.PublicKey
123125
issuer string
124126
}
125127

@@ -192,17 +194,49 @@ func NewOIDCService(
192194
}
193195
}
194196

195-
der := x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)
196-
if der == nil {
197-
return nil, errors.New("failed to marshal public key")
197+
var publicKey crypto.PublicKey
198+
199+
fpublicKey, err := os.ReadFile(config.OIDC.PublicKeyPath)
200+
201+
if err != nil && !errors.Is(err, os.ErrNotExist) {
202+
return nil, fmt.Errorf("failed to read public key: %w", err)
198203
}
199-
encoded := pem.EncodeToMemory(&pem.Block{
200-
Type: "RSA PUBLIC KEY",
201-
Bytes: der,
202-
})
203-
err = os.WriteFile(config.OIDC.PublicKeyPath, encoded, 0644)
204-
if err != nil {
205-
return nil, err
204+
205+
if errors.Is(err, os.ErrNotExist) {
206+
publicKey = privateKey.Public()
207+
der := x509.MarshalPKCS1PublicKey(publicKey.(*rsa.PublicKey))
208+
if der == nil {
209+
return nil, errors.New("failed to marshal public key")
210+
}
211+
encoded := pem.EncodeToMemory(&pem.Block{
212+
Type: "RSA PUBLIC KEY",
213+
Bytes: der,
214+
})
215+
log.App.Trace().Str("type", "RSA PUBLIC KEY").Msg("Generated public RSA key")
216+
err = os.WriteFile(config.OIDC.PublicKeyPath, encoded, 0644)
217+
if err != nil {
218+
return nil, err
219+
}
220+
} else {
221+
block, _ := pem.Decode(fpublicKey)
222+
if block == nil {
223+
return nil, errors.New("failed to decode public key")
224+
}
225+
log.App.Trace().Str("type", block.Type).Msg("Loaded public key")
226+
switch block.Type {
227+
case "RSA PUBLIC KEY":
228+
publicKey, err = x509.ParsePKCS1PublicKey(block.Bytes)
229+
if err != nil {
230+
return nil, fmt.Errorf("failed to parse public key: %w", err)
231+
}
232+
case "PUBLIC KEY":
233+
publicKey, err = x509.ParsePKIXPublicKey(block.Bytes)
234+
if err != nil {
235+
return nil, fmt.Errorf("failed to parse public key: %w", err)
236+
}
237+
default:
238+
return nil, fmt.Errorf("unsupported public key type: %s", block.Type)
239+
}
206240
}
207241

208242
// We will reorganize the client into a map with the client ID as the key
@@ -237,6 +271,7 @@ func NewOIDCService(
237271

238272
clients: clients,
239273
privateKey: privateKey,
274+
publicKey: publicKey,
240275
issuer: issuer,
241276
}
242277

0 commit comments

Comments
 (0)