mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-21 03:58:07 +02:00
* hpke: add HPKE key to JWKS endpoint * fix test, add http caching headers * fix error message * use pointers
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package hpke
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
)
|
|
|
|
// URL Parameters
|
|
const (
|
|
ParamSenderPublicKey = "pomerium_hpke_sender_pub"
|
|
ParamQuery = "pomerium_hpke_query"
|
|
)
|
|
|
|
// IsEncryptedURL returns true if the url.Values contain an HPKE encrypted query.
|
|
func IsEncryptedURL(values url.Values) bool {
|
|
return values.Has(ParamSenderPublicKey) && values.Has(ParamQuery)
|
|
}
|
|
|
|
// EncryptURLValues encrypts URL values using the Seal method.
|
|
func EncryptURLValues(
|
|
senderPrivateKey *PrivateKey,
|
|
receiverPublicKey *PublicKey,
|
|
values url.Values,
|
|
) (encrypted url.Values, err error) {
|
|
values = withoutHPKEParams(values)
|
|
|
|
sealed, err := Seal(senderPrivateKey, receiverPublicKey, []byte(values.Encode()))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("hpke: failed to seal URL values %w", err)
|
|
}
|
|
|
|
return url.Values{
|
|
ParamSenderPublicKey: {senderPrivateKey.PublicKey().String()},
|
|
ParamQuery: {encode(sealed)},
|
|
}, nil
|
|
}
|
|
|
|
// DecryptURLValues decrypts URL values using the Open method.
|
|
func DecryptURLValues(
|
|
receiverPrivateKey *PrivateKey,
|
|
encrypted url.Values,
|
|
) (senderPublicKey *PublicKey, values url.Values, err error) {
|
|
if !encrypted.Has(ParamSenderPublicKey) {
|
|
return nil, nil, fmt.Errorf("hpke: missing sender public key in query parameters")
|
|
}
|
|
if !encrypted.Has(ParamQuery) {
|
|
return nil, nil, fmt.Errorf("hpke: missing encrypted query in query parameters")
|
|
}
|
|
|
|
senderPublicKey, err = PublicKeyFromString(encrypted.Get(ParamSenderPublicKey))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("hpke: invalid sender public key parameter: %w", err)
|
|
}
|
|
|
|
sealed, err := decode(encrypted.Get(ParamQuery))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("hpke: failed decoding query parameter: %w", err)
|
|
}
|
|
|
|
message, err := Open(receiverPrivateKey, senderPublicKey, sealed)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("hpke: failed to open sealed message: %w", err)
|
|
}
|
|
|
|
decrypted, err := url.ParseQuery(string(message))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("hpke: invalid query parameter: %w", err)
|
|
}
|
|
|
|
values = withoutHPKEParams(encrypted)
|
|
for k, vs := range decrypted {
|
|
values[k] = vs
|
|
}
|
|
|
|
return senderPublicKey, values, err
|
|
}
|
|
|
|
func withoutHPKEParams(values url.Values) url.Values {
|
|
filtered := make(url.Values)
|
|
for k, vs := range values {
|
|
if k != ParamSenderPublicKey && k != ParamQuery {
|
|
filtered[k] = vs
|
|
}
|
|
}
|
|
return filtered
|
|
}
|