Milan Pavlik d9ccc1d141
[papi] OIDC service signs state with HS256, reusing signing PK - WEB-206 (#17328)
* [papi] OIDC service signs state with RSA256

* Fix

* retest

* fix

* add test
2023-04-24 17:14:45 +08:00

82 lines
1.9 KiB
Go

// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
package jws
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"github.com/gitpod-io/gitpod/components/public-api/go/config"
)
type Key struct {
ID string
Private *rsa.PrivateKey
Raw []byte
// We don't need PublicKey because we can derive the public key from the private key
}
// KeySet encodes a collection of keys to use
// There's always a Signing key, but optionally there are also
// older keys which can be used to verify.
type KeySet struct {
Signing Key
Validating []Key
}
func NewKeySetFromAuthPKI(pki config.AuthPKIConfiguration) (KeySet, error) {
signing, err := readKeyPair(pki.Signing)
if err != nil {
return KeySet{}, fmt.Errorf("failed to read signing key: %w", err)
}
var validating []Key
for _, keypair := range pki.Validating {
key, err := readKeyPair(keypair)
if err != nil {
return KeySet{}, fmt.Errorf("failed to read validating key: %w", err)
}
validating = append(validating, key)
}
return KeySet{
Signing: signing,
Validating: validating,
}, nil
}
func readKeyPair(keypair config.KeyPair) (Key, error) {
pk, raw, err := readPrivateKeyFromFile(keypair.PrivateKeyPath)
if err != nil {
return Key{}, err
}
return Key{
ID: keypair.ID,
Private: pk,
Raw: raw,
}, nil
}
func readPrivateKeyFromFile(filepath string) (*rsa.PrivateKey, []byte, error) {
bytes, err := ioutil.ReadFile(filepath)
if err != nil {
return nil, nil, fmt.Errorf("failed to read private key from %s: %w", filepath, err)
}
block, _ := pem.Decode(bytes)
parseResult, _ := x509.ParsePKCS8PrivateKey(block.Bytes)
key, ok := parseResult.(*rsa.PrivateKey)
if !ok {
return nil, nil, fmt.Errorf("file %s does not contain RSA Private Key", filepath)
}
return key, bytes, nil
}