snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
55
oryx/josex/encoding.go
Normal file
55
oryx/josex/encoding.go
Normal file
@@ -0,0 +1,55 @@
|
||||
/*-
|
||||
* Copyright 2019 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josex
|
||||
|
||||
import "io"
|
||||
|
||||
// Base64Reader wraps an input stream consisting of either standard or url-safe
|
||||
// base64 data, and maps it to a raw (unpadded) standard encoding. This can be used
|
||||
// to read any base64-encoded data as input, whether padded, unpadded, standard or
|
||||
// url-safe.
|
||||
type Base64Reader struct {
|
||||
In io.Reader
|
||||
}
|
||||
|
||||
func (r Base64Reader) Read(p []byte) (n int, err error) {
|
||||
n, err = r.In.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range n {
|
||||
switch p[i] {
|
||||
// Map - to +
|
||||
case 0x2D:
|
||||
p[i] = 0x2B
|
||||
// Map _ to /
|
||||
case 0x5F:
|
||||
p[i] = 0x2F
|
||||
// Strip =
|
||||
case 0x3D:
|
||||
n = i
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
err = io.EOF
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
121
oryx/josex/generate.go
Normal file
121
oryx/josex/generate.go
Normal file
@@ -0,0 +1,121 @@
|
||||
/*-
|
||||
* Copyright 2019 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josex
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
)
|
||||
|
||||
// NewSigningKey generates a keypair for corresponding SignatureAlgorithm.
|
||||
func NewSigningKey(alg jose.SignatureAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error) {
|
||||
switch alg {
|
||||
case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
|
||||
keylen := map[jose.SignatureAlgorithm]int{
|
||||
jose.ES256: 256,
|
||||
jose.ES384: 384,
|
||||
jose.ES512: 521, // sic!
|
||||
jose.EdDSA: 256,
|
||||
}
|
||||
if bits != 0 && bits != keylen[alg] {
|
||||
return nil, nil, errors.New("invalid elliptic curve key size, this algorithm does not support arbitrary size")
|
||||
}
|
||||
case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
|
||||
if bits == 0 {
|
||||
bits = 2048
|
||||
}
|
||||
if bits < 2048 {
|
||||
return nil, nil, errors.New("invalid key size for RSA key, 2048 or more is required")
|
||||
}
|
||||
}
|
||||
switch alg {
|
||||
case jose.ES256:
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
case jose.ES384:
|
||||
key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
case jose.ES512:
|
||||
key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
case jose.EdDSA:
|
||||
pub, key, err := ed25519.GenerateKey(rand.Reader)
|
||||
return pub, key, err
|
||||
case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
|
||||
key, err := rsa.GenerateKey(rand.Reader, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown algorithm %s for signing key", alg)
|
||||
}
|
||||
}
|
||||
|
||||
// NewEncryptionKey generates a keypair for corresponding KeyAlgorithm.
|
||||
func NewEncryptionKey(alg jose.KeyAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error) {
|
||||
switch alg {
|
||||
case jose.RSA1_5, jose.RSA_OAEP, jose.RSA_OAEP_256:
|
||||
if bits == 0 {
|
||||
bits = 2048
|
||||
}
|
||||
if bits < 2048 {
|
||||
return nil, nil, errors.New("invalid key size for RSA key, 2048 or more is required")
|
||||
}
|
||||
key, err := rsa.GenerateKey(rand.Reader, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
case jose.ECDH_ES, jose.ECDH_ES_A128KW, jose.ECDH_ES_A192KW, jose.ECDH_ES_A256KW:
|
||||
var crv elliptic.Curve
|
||||
switch bits {
|
||||
case 0, 256:
|
||||
crv = elliptic.P256()
|
||||
case 384:
|
||||
crv = elliptic.P384()
|
||||
case 521:
|
||||
crv = elliptic.P521()
|
||||
default:
|
||||
return nil, nil, errors.New("invalid elliptic curve key size, use one of 256, 384, or 521")
|
||||
}
|
||||
key, err := ecdsa.GenerateKey(crv, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return key.Public(), key, err
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown algorithm %s for encryption key", alg)
|
||||
}
|
||||
}
|
||||
29
oryx/josex/public.go
Normal file
29
oryx/josex/public.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package josex
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
)
|
||||
|
||||
// ToPublicKey returns the public key of the given private key.
|
||||
func ToPublicKey(k *jose.JSONWebKey) jose.JSONWebKey {
|
||||
if key := k.Public(); key.Key != nil {
|
||||
return key
|
||||
}
|
||||
|
||||
// HSM workaround - jose does not understand crypto.Signer / HSM so we need to manually
|
||||
// extract the public key.
|
||||
switch key := k.Key.(type) {
|
||||
case crypto.Signer:
|
||||
newKey := *k
|
||||
newKey.Key = key.Public()
|
||||
return newKey
|
||||
case jose.OpaqueSigner:
|
||||
newKey := *k
|
||||
newKey.Key = key.Public().Key
|
||||
return newKey
|
||||
}
|
||||
|
||||
return jose.JSONWebKey{}
|
||||
}
|
||||
103
oryx/josex/utils.go
Normal file
103
oryx/josex/utils.go
Normal file
@@ -0,0 +1,103 @@
|
||||
/*-
|
||||
* Copyright 2019 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josex
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
)
|
||||
|
||||
// LoadJSONWebKey returns a *jose.JSONWebKey for a given JSON string.
|
||||
func LoadJSONWebKey(json []byte, pub bool) (*jose.JSONWebKey, error) {
|
||||
var jwk jose.JSONWebKey
|
||||
err := jwk.UnmarshalJSON(json)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !jwk.Valid() {
|
||||
return nil, errors.New("invalid JWK key")
|
||||
}
|
||||
if jwk.IsPublic() != pub {
|
||||
return nil, errors.New("priv/pub JWK key mismatch")
|
||||
}
|
||||
return &jwk, nil
|
||||
}
|
||||
|
||||
// LoadPublicKey loads a public key from PEM/DER/JWK-encoded data.
|
||||
func LoadPublicKey(data []byte) (interface{}, error) {
|
||||
input := data
|
||||
|
||||
block, _ := pem.Decode(data)
|
||||
if block != nil {
|
||||
input = block.Bytes
|
||||
}
|
||||
|
||||
// Try to load SubjectPublicKeyInfo
|
||||
pub, err0 := x509.ParsePKIXPublicKey(input)
|
||||
if err0 == nil {
|
||||
return pub, nil
|
||||
}
|
||||
|
||||
cert, err1 := x509.ParseCertificate(input)
|
||||
if err1 == nil {
|
||||
return cert.PublicKey, nil
|
||||
}
|
||||
|
||||
jwk, err2 := LoadJSONWebKey(data, true)
|
||||
if err2 == nil {
|
||||
return jwk, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("square/go-jose: parse error, got '%s', '%s' and '%s'", err0, err1, err2)
|
||||
}
|
||||
|
||||
// LoadPrivateKey loads a private key from PEM/DER/JWK-encoded data.
|
||||
func LoadPrivateKey(data []byte) (interface{}, error) {
|
||||
input := data
|
||||
|
||||
block, _ := pem.Decode(data)
|
||||
if block != nil {
|
||||
input = block.Bytes
|
||||
}
|
||||
|
||||
var priv interface{}
|
||||
priv, err0 := x509.ParsePKCS1PrivateKey(input)
|
||||
if err0 == nil {
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
priv, err1 := x509.ParsePKCS8PrivateKey(input)
|
||||
if err1 == nil {
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
priv, err2 := x509.ParseECPrivateKey(input)
|
||||
if err2 == nil {
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
jwk, err3 := LoadJSONWebKey(input, false)
|
||||
if err3 == nil {
|
||||
return jwk, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("square/go-jose: parse error, got '%s', '%s', '%s' and '%s'", err0, err1, err2, err3)
|
||||
}
|
||||
Reference in New Issue
Block a user