From bb56f40ca1edf15c738004ddd5199d24dfbab35b Mon Sep 17 00:00:00 2001 From: Tyler Biscoe Date: Tue, 19 Mar 2024 14:30:23 -0400 Subject: [PATCH 1/2] added a new encryption keypair --- README.md | 1 - sdk/auth/access_token_source.go | 1 + sdk/auth/authn_test.go | 1 + sdk/idp_access_token_source.go | 98 ++++++++++++++++++--------------- sdk/kas_client.go | 2 +- 5 files changed, 58 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index f237db8c45..87277f61b5 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ Note: support was added to provision a set of fixture data into the database. Run `go run . provision fixtures -h` for more information. ### Test - ```bash grpcurl -plaintext localhost:8080 list diff --git a/sdk/auth/access_token_source.go b/sdk/auth/access_token_source.go index dd72dc6a03..87bc9f06f8 100644 --- a/sdk/auth/access_token_source.go +++ b/sdk/auth/access_token_source.go @@ -11,5 +11,6 @@ type AccessTokenSource interface { DecryptWithDPoPKey(data []byte) ([]byte, error) MakeToken(func(jwk.Key) ([]byte, error)) ([]byte, error) DPoPPublicKeyPEM() string + EncryptionPublicKeyPEM() string RefreshAccessToken() error } diff --git a/sdk/auth/authn_test.go b/sdk/auth/authn_test.go index 61a6b7b1d4..3d47470716 100644 --- a/sdk/auth/authn_test.go +++ b/sdk/auth/authn_test.go @@ -55,6 +55,7 @@ func (fake FakeAccessTokenSource) MakeToken(tokenMaker func(jwk.Key) ([]byte, er func (fake FakeAccessTokenSource) DPoPPublicKeyPEM() string { return "this is the PEM" } +func (fake FakeAccessTokenSource) EncryptionPublicKeyPEM() string { return "this is the PEM" } func (fake FakeAccessTokenSource) RefreshAccessToken() error { return errors.New("can't refresh this one") } diff --git a/sdk/idp_access_token_source.go b/sdk/idp_access_token_source.go index 30c398deba..b5aa37c461 100644 --- a/sdk/idp_access_token_source.go +++ b/sdk/idp_access_token_source.go @@ -22,56 +22,51 @@ const ( dpopKeySize = 2048 ) -func getNewDPoPKey() (string, jwk.Key, *crypto.AsymDecryption, error) { //nolint:ireturn // this is only internal - dpopPrivate, err := rsa.GenerateKey(rand.Reader, dpopKeySize) +func GenerateKeyPair() (string, string, jwk.Key, error) { + rawPrivateKey, err := rsa.GenerateKey(rand.Reader, dpopKeySize) if err != nil { - return "", nil, nil, fmt.Errorf("error creating DPoP keypair: %w", err) + return "", "", nil, fmt.Errorf("error creating DPoP keypair: %w", err) } - dpopKey, err := jwk.FromRaw(dpopPrivate) + jwkPrivateKey, err := jwk.FromRaw(rawPrivateKey) if err != nil { - return "", nil, nil, fmt.Errorf("error creating JWK: %w", err) + return "", "", nil, fmt.Errorf("error creating JWK: %w", err) } - err = dpopKey.Set("alg", jwa.RS256) + err = jwkPrivateKey.Set("alg", jwa.RS256) if err != nil { - return "", nil, nil, fmt.Errorf("error setting the key algorithm: %w", err) + return "", "", nil, fmt.Errorf("error setting the key algorithm: %w", err) } - dpopKeyDER, err := x509.MarshalPKCS8PrivateKey(dpopPrivate) + derPrivateKey, err := x509.MarshalPKCS8PrivateKey(rawPrivateKey) if err != nil { - return "", nil, nil, fmt.Errorf("error marshalling private key: %w", err) + return "", "", nil, fmt.Errorf("error marshalling private key: %w", err) } - var dpopPrivatePEM strings.Builder + var privateKeyPem strings.Builder - err = pem.Encode(&dpopPrivatePEM, &pem.Block{ + err = pem.Encode(&privateKeyPem, &pem.Block{ Type: "PRIVATE KEY", - Bytes: dpopKeyDER, + Bytes: derPrivateKey, }) if err != nil { - return "", nil, nil, fmt.Errorf("error encoding private key to PEM") + return "", "", nil, fmt.Errorf("error encoding private key to PEM") } - dpopPublic := dpopPrivate.Public() - dpopPublicDER, err := x509.MarshalPKIXPublicKey(dpopPublic) + rawPublicKey := rawPrivateKey.Public() + derPublicKey, err := x509.MarshalPKIXPublicKey(rawPublicKey) if err != nil { - return "", nil, nil, fmt.Errorf("error marshalling public key: %w", err) + return "", "", nil, fmt.Errorf("error marshalling public key: %w", err) } - var dpopPublicKeyPEM strings.Builder - err = pem.Encode(&dpopPublicKeyPEM, &pem.Block{ + var publicKeyPem strings.Builder + err = pem.Encode(&publicKeyPem, &pem.Block{ Type: "PUBLIC KEY", - Bytes: dpopPublicDER, + Bytes: derPublicKey, }) if err != nil { - return "", nil, nil, fmt.Errorf("error encoding public key to PEM") + return "", "", nil, fmt.Errorf("error encoding public key to PEM") } - asymDecryption, err := crypto.NewAsymDecryption(dpopPrivatePEM.String()) - if err != nil { - return "", nil, nil, fmt.Errorf("error creating asymmetric decryptor: %w", err) - } - - return dpopPublicKeyPEM.String(), dpopKey, &asymDecryption, nil + return publicKeyPem.String(), privateKeyPem.String(), jwkPrivateKey, nil } /* @@ -79,37 +74,50 @@ Credentials that allow us to connect to an IDP and obtain an access token that i to a DPoP key */ type IDPAccessTokenSource struct { - credentials oauth.ClientCredentials - idpTokenEndpoint url.URL - token *oauth2.Token - scopes []string - dpopKey jwk.Key - asymDecryption crypto.AsymDecryption - dpopPEM string - tokenMutex *sync.Mutex + credentials oauth.ClientCredentials + idpTokenEndpoint url.URL + token *oauth2.Token + scopes []string + dpopKey jwk.Key + encryptionPublicKeyPEM string + asymDecryption crypto.AsymDecryption + dpopPEM string + tokenMutex *sync.Mutex } func NewIDPAccessTokenSource( credentials oauth.ClientCredentials, idpTokenEndpoint string, scopes []string) (IDPAccessTokenSource, error) { endpoint, err := url.Parse(idpTokenEndpoint) + if err != nil { return IDPAccessTokenSource{}, fmt.Errorf("invalid url [%s]: %w", idpTokenEndpoint, err) } - dpopPublicKeyPEM, dpopKey, asymDecryption, err := getNewDPoPKey() + dpopPublicKeyPem, _, dpopKey, err := GenerateKeyPair() + if err != nil { + return IDPAccessTokenSource{}, err + } + + encryptionPublicKeyPem, encryptionPrivateKeyPem, _, err := GenerateKeyPair() + if err != nil { + return IDPAccessTokenSource{}, err + } + + asymDecryption, err := crypto.NewAsymDecryption(encryptionPrivateKeyPem) if err != nil { return IDPAccessTokenSource{}, err } creds := IDPAccessTokenSource{ - credentials: credentials, - idpTokenEndpoint: *endpoint, - token: nil, - scopes: scopes, - asymDecryption: *asymDecryption, - dpopKey: dpopKey, - dpopPEM: dpopPublicKeyPEM, - tokenMutex: &sync.Mutex{}, + credentials: credentials, + idpTokenEndpoint: *endpoint, + token: nil, + scopes: scopes, + asymDecryption: asymDecryption, + encryptionPublicKeyPEM: encryptionPublicKeyPem, + dpopKey: dpopKey, + dpopPEM: dpopPublicKeyPem, + tokenMutex: &sync.Mutex{}, } return creds, nil @@ -151,3 +159,7 @@ func (t *IDPAccessTokenSource) MakeToken(tokenMaker func(jwk.Key) ([]byte, error func (t *IDPAccessTokenSource) DPoPPublicKeyPEM() string { return t.dpopPEM } + +func (t *IDPAccessTokenSource) EncryptionPublicKeyPEM() string { + return t.encryptionPublicKeyPEM +} diff --git a/sdk/kas_client.go b/sdk/kas_client.go index 86ca168ae7..f7a8c24322 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -110,7 +110,7 @@ func (k *KASClient) getRewrapRequest(keyAccess KeyAccess, policy string) (*kas.R requestBody := rewrapRequestBody{ Policy: policy, KeyAccess: keyAccess, - ClientPublicKey: k.accessTokenSource.DPoPPublicKeyPEM(), + ClientPublicKey: k.accessTokenSource.EncryptionPublicKeyPEM(), } requestBodyJSON, err := json.Marshal(requestBody) if err != nil { From 65909cd1d3465b8219542171c01c594467548312 Mon Sep 17 00:00:00 2001 From: Tyler Biscoe Date: Tue, 19 Mar 2024 14:33:46 -0400 Subject: [PATCH 2/2] Made a function private --- sdk/idp_access_token_source.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/idp_access_token_source.go b/sdk/idp_access_token_source.go index b5aa37c461..15aa8a04c6 100644 --- a/sdk/idp_access_token_source.go +++ b/sdk/idp_access_token_source.go @@ -22,7 +22,7 @@ const ( dpopKeySize = 2048 ) -func GenerateKeyPair() (string, string, jwk.Key, error) { +func generateKeyPair() (string, string, jwk.Key, error) { rawPrivateKey, err := rsa.GenerateKey(rand.Reader, dpopKeySize) if err != nil { return "", "", nil, fmt.Errorf("error creating DPoP keypair: %w", err) @@ -93,12 +93,12 @@ func NewIDPAccessTokenSource( return IDPAccessTokenSource{}, fmt.Errorf("invalid url [%s]: %w", idpTokenEndpoint, err) } - dpopPublicKeyPem, _, dpopKey, err := GenerateKeyPair() + dpopPublicKeyPem, _, dpopKey, err := generateKeyPair() if err != nil { return IDPAccessTokenSource{}, err } - encryptionPublicKeyPem, encryptionPrivateKeyPem, _, err := GenerateKeyPair() + encryptionPublicKeyPem, encryptionPrivateKeyPem, _, err := generateKeyPair() if err != nil { return IDPAccessTokenSource{}, err }