Skip to content

Commit

Permalink
jwe: Support overriding the algorithm when supplying a JWK
Browse files Browse the repository at this point in the history
Otherwise, the current code makes it impossible to supply a JWK-encoded ECDSA public key in the encryption config. (ParsePublicKey returns parseJWKPublicKey which returns the JWK itself; hence the switch-case fails to notice the ECDSA key inside the JWK)

Signed-off-by: Bojidar Marinov <bojidar.marinov.bg@gmail.com>
  • Loading branch information
bojidar-bg committed Nov 16, 2023
1 parent c0e1fd5 commit 42928e3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
6 changes: 5 additions & 1 deletion keywrap/jwe/keywrapper_jwe.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,13 @@ func addPubKeys(joseRecipients *[]jose.Recipient, pubKeys [][]byte) error {
}

alg := jose.RSA_OAEP
switch key.(type) {
switch key := key.(type) {
case *ecdsa.PublicKey:
alg = jose.ECDH_ES_A256KW
case *jose.JSONWebKey:
if key.Algorithm != "" {
alg = jose.KeyAlgorithm(key.Algorithm)
}
}

*joseRecipients = append(*joseRecipients, jose.Recipient{
Expand Down
36 changes: 36 additions & 0 deletions keywrap/jwe/keywrapper_jwe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ func createValidJweCcs() ([]*config.CryptoConfig, error) {
return nil, err
}

ecKey, err := utils.CreateECDSAKey(elliptic.P521())
if err != nil {
return nil, err
}

jweEcPrivKeyJwk, err := jose.JSONWebKey{Key: ecKey, Algorithm: string(jose.ECDH_ES_A256KW)}.MarshalJSON()
if err != nil {
return nil, err
}

jweEcPubKeyJwk, err := jose.JSONWebKey{Key: &ecKey.PublicKey, Algorithm: string(jose.ECDH_ES_A256KW)}.MarshalJSON()
if err != nil {
return nil, err
}

validJweCcs := []*config.CryptoConfig{
// Key 1
{
Expand Down Expand Up @@ -226,6 +241,27 @@ func createValidJweCcs() ([]*config.CryptoConfig, error) {
},
},
},
// EC Key (JWK format)
{
EncryptConfig: &config.EncryptConfig{
Parameters: map[string][][]byte{
"pubkeys": {jweEcPubKeyJwk},
},
DecryptConfig: config.DecryptConfig{
Parameters: map[string][][]byte{
"privkeys": {jweEcPrivKeyJwk},
"privkeys-passwords": {oneEmpty},
},
},
},

DecryptConfig: &config.DecryptConfig{
Parameters: map[string][][]byte{
"privkeys": {jweEcPrivKeyJwk},
"privkeys-passwords": {oneEmpty},
},
},
},
}
return validJweCcs, nil
}
Expand Down
13 changes: 11 additions & 2 deletions utils/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ func CreateRSAKey(bits int) (*rsa.PrivateKey, error) {
return key, nil
}

// CreateECDSAKey creates an elliptic curve key for the given curve
func CreateECDSAKey(curve elliptic.Curve) (*ecdsa.PrivateKey, error) {
key, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
return nil, fmt.Errorf("ecdsa.GenerateKey failed: %w", err)
}
return key, nil
}

// CreateRSATestKey creates an RSA key of the given size and returns
// the public and private key in PEM or DER format
func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte, error) {
Expand Down Expand Up @@ -85,9 +94,9 @@ func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte
// CreateECDSATestKey creates and elliptic curve key for the given curve and returns
// the public and private key in DER format
func CreateECDSATestKey(curve elliptic.Curve) ([]byte, []byte, error) {
key, err := ecdsa.GenerateKey(curve, rand.Reader)
key, err := CreateECDSAKey(curve)
if err != nil {
return nil, nil, fmt.Errorf("ecdsa.GenerateKey failed: %w", err)
return nil, nil, err
}

pubData, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
Expand Down

0 comments on commit 42928e3

Please sign in to comment.