-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #163 from maxlaverse/argon2
Fix issues with Argon2
- Loading branch information
Showing
25 changed files
with
1,043 additions
and
837 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package keybuilder | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/models" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestArgon2(t *testing.T) { | ||
key, err := buildKey("test1234", "somesalt", models.KdfConfiguration{ | ||
KdfType: models.KdfTypeArgon2, | ||
KdfIterations: 3, | ||
KdfMemory: 64, | ||
KdfParallelism: 4, | ||
}) | ||
|
||
assert.NoError(t, err) | ||
assert.Equal(t, "Key: CAgX8/OUnQXSAzipUdqaQ9CFCflNf2lowXvfbpzNmXU=\nEncryptionKey: CAgX8/OUnQXSAzipUdqaQ9CFCflNf2lowXvfbpzNmXU=\nMacKey: \n", key.Summary()) | ||
} | ||
|
||
func TestArgon2WithTooLittleParallelism(t *testing.T) { | ||
key, err := buildKey("test1234", "somesalt", models.KdfConfiguration{ | ||
KdfType: models.KdfTypeArgon2, | ||
KdfIterations: 3, | ||
KdfMemory: 64, | ||
KdfParallelism: 0, | ||
}) | ||
|
||
assert.Errorf(t, err, "panicked: argon2: parallelism degree too low") | ||
assert.Nil(t, key) | ||
} |
125 changes: 125 additions & 0 deletions
125
internal/bitwarden/embedded/fixtures/create_accounts_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package fixtures | ||
|
||
import ( | ||
"context" | ||
"crypto/x509" | ||
"encoding/base64" | ||
"encoding/pem" | ||
"net/http" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/crypto" | ||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/crypto/keybuilder" | ||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/embedded" | ||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/models" | ||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/webapi" | ||
) | ||
|
||
// This is only used to generate test data | ||
func TestCreateTestAccounts(t *testing.T) { | ||
t.Skip() | ||
createTestAccount(t, Pdkdf2Email, models.KdfConfiguration{ | ||
KdfType: models.KdfTypePBKDF2_SHA256, | ||
KdfIterations: 600000, | ||
}) | ||
createTestAccount(t, Argon2Email, models.KdfConfiguration{ | ||
KdfType: models.KdfTypeArgon2, | ||
KdfIterations: 3, | ||
KdfMemory: 64, | ||
KdfParallelism: 4, | ||
}) | ||
} | ||
|
||
func createTestAccount(t *testing.T, accountEmail string, kdfConfig models.KdfConfiguration) { | ||
ctx := context.Background() | ||
|
||
mockName := strings.Split(accountEmail, "@")[0] | ||
|
||
preloginKey, err := keybuilder.BuildPreloginKey(TestPassword, accountEmail, kdfConfig) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
hashedPassword := crypto.HashPassword(TestPassword, *preloginKey, false) | ||
|
||
block, _ := pem.Decode([]byte(RsaPrivateKey)) | ||
if block == nil { | ||
t.Fatal(err) | ||
} | ||
|
||
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
encryptionKeyBytes, err := base64.StdEncoding.DecodeString(EncryptionKey) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
newEncryptionKey, encryptedEncryptionKey, err := keybuilder.EncryptEncryptionKey(*preloginKey, encryptionKeyBytes) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
publicKey, encryptedPrivateKey, err := keybuilder.EncryptRSAKeyPair(*newEncryptionKey, privateKey) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
signupRequest := webapi.SignupRequest{ | ||
Email: accountEmail, | ||
Name: accountEmail, | ||
MasterPasswordHash: hashedPassword, | ||
Key: encryptedEncryptionKey, | ||
Kdf: kdfConfig.KdfType, | ||
KdfIterations: kdfConfig.KdfIterations, | ||
KdfMemory: kdfConfig.KdfMemory, | ||
KdfParallelism: kdfConfig.KdfParallelism, | ||
Keys: webapi.KeyPair{ | ||
PublicKey: publicKey, | ||
EncryptedPrivateKey: encryptedPrivateKey, | ||
}, | ||
} | ||
|
||
client := webapi.NewClient(ServerURL) | ||
err = client.RegisterUser(ctx, signupRequest) | ||
if err != nil && !strings.Contains(err.Error(), "Registration not allowed or user already exists") { | ||
t.Fatal(err) | ||
} | ||
|
||
httpClient := http.Client{ | ||
Transport: &diskTransport{ | ||
Prefix: mockName, | ||
}, | ||
} | ||
vault := embedded.NewWebAPIVault(ServerURL, embedded.WithHttpOptions(webapi.WithCustomClient(httpClient))) | ||
|
||
err = vault.LoginWithPassword(ctx, accountEmail, TestPassword) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
apiKey, err := vault.GetAPIKey(ctx, accountEmail, TestPassword) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = vault.LoginWithAPIKey(ctx, TestPassword, apiKey.ClientID, apiKey.ClientSecret) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = vault.CreateObject(ctx, models.Object{ | ||
Object: models.ObjectTypeItem, | ||
Type: models.ItemTypeLogin, | ||
Name: "Item in own Vault", | ||
Login: models.Login{ | ||
Username: "my-username", | ||
}, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package fixtures | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"os" | ||
"strings" | ||
) | ||
|
||
type diskTransport struct { | ||
Transport http.RoundTripper | ||
Prefix string | ||
} | ||
|
||
func (d *diskTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
transport := d.Transport | ||
if transport == nil { | ||
transport = http.DefaultTransport | ||
} | ||
|
||
resp, err := transport.RoundTrip(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if err := d.saveResponseToFile(req, resp); err != nil { | ||
return nil, fmt.Errorf("error saving response to file: %w", err) | ||
} | ||
|
||
return resp, nil | ||
} | ||
|
||
func (d *diskTransport) saveResponseToFile(req *http.Request, resp *http.Response) error { | ||
filename := fmt.Sprintf("%s_%s%s.json", d.Prefix, req.Method, sanitizeFilename(resp.Request.URL.EscapedPath())) | ||
|
||
data, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
resp.Body = io.NopCloser(bytes.NewReader(data)) | ||
|
||
var jsonData map[string]interface{} | ||
if err := json.Unmarshal(data, &jsonData); err != nil { | ||
return err | ||
} | ||
|
||
prettyData, err := json.MarshalIndent(jsonData, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return os.WriteFile(filename, prettyData, 0644) | ||
} | ||
|
||
func sanitizeFilename(url string) string { | ||
replacer := []string{ | ||
":", "_", | ||
"/", "_", | ||
"\\", "_", | ||
"?", "_", | ||
"&", "_", | ||
"=", "_", | ||
"%", "_", | ||
} | ||
replacerMap := strings.NewReplacer(replacer...) | ||
return replacerMap.Replace(url) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package fixtures | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/jarcoal/httpmock" | ||
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/webapi" | ||
) | ||
|
||
const ( | ||
mockedServerUrl = "http://127.0.0.1:8081" | ||
) | ||
|
||
func MockedClient(t *testing.T, name string) webapi.Client { | ||
client := http.Client{Transport: httpmock.DefaultTransport} | ||
|
||
files, err := os.ReadDir("fixtures") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
t.Logf("Found %d responders", len(files)) | ||
for _, file := range files { | ||
if !strings.HasSuffix(file.Name(), ".json") || !strings.HasPrefix(file.Name(), fmt.Sprintf("%s_", name)) { | ||
continue | ||
} | ||
|
||
data, err := os.ReadFile(fmt.Sprintf("%s/%s", "fixtures", file.Name())) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
tmp := strings.Split(file.Name(), "_") | ||
name = tmp[0] | ||
method := strings.ToUpper(tmp[1]) | ||
mockUrl := strings.Join(tmp[2:], "/") | ||
|
||
mockUrl, _ = strings.CutSuffix(mockUrl, ".json") | ||
mockUrl = fmt.Sprintf("%s/%s", mockedServerUrl, mockUrl) | ||
t.Logf("Registering responder for %s %s", method, mockUrl) | ||
|
||
httpmock.RegisterResponder(method, mockUrl, | ||
httpmock.NewStringResponder(200, string(data))) | ||
} | ||
|
||
return webapi.NewClient(mockedServerUrl, webapi.WithCustomClient(client), webapi.DisableRetries()) | ||
} |
22 changes: 22 additions & 0 deletions
22
internal/bitwarden/embedded/fixtures/test-kdf0_GET_api_accounts_profile.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"_status": 0, | ||
"avatarColor": null, | ||
"culture": "en-US", | ||
"email": "[email protected]", | ||
"emailVerified": true, | ||
"forcePasswordReset": false, | ||
"id": "aaf15bd1-4f51-4ba0-ade8-9dc2ec0fd2c3", | ||
"key": "2.fl6CmmK/o/THYg8Y3Z5fJw==|sEjr1DMSe+Hgg7DRU8Z2wqZiZWIySrY63E8ISwQ7Q9vpxUPDQPifTW9oW0ZjcnKE4Xl4fxP89LO5xce+y+yR1yAQpnVcm2wMBx0OXM1xaAU=|9wNu2sNXt7ECSXCYsDL1ctWw02GGT1y7Pkx2NxIyD0A=", | ||
"masterPasswordHint": null, | ||
"name": "[email protected]", | ||
"object": "profile", | ||
"organizations": [], | ||
"premium": true, | ||
"premiumFromOrganization": false, | ||
"privateKey": "2.11j1IvphccY0UkZov7ZbmQ==|4J34a16NM+krEXyDUkHVUNL2sSA7dph4EBCLWoDkmDoljqMZh5IxA7M51yZTNB6/uqGgJZJX0uU+B4RSn2s2JoFG/VizMmgSIJkTIr6WuA7taEzyIFRi7sY980W02pnLeb8fGV8EXrZk1Bj0UzAFukNGoeS2CHWbm0bZKRvDxl5Vw40V3Lt6GzHTb6X+4k4Ovg0UKgm2mqMWzxxjmCfy+G1R0vlsAtqg14n2ax5f3Jn4ajGDvT2BQia9EFYFkie/SfqgsYbtvou4DvyCTEWh0j9Cre1QIJQ9AZ4AHAzGwIKFhpN7sWjsfw6yTGmvxAfflCMFzCdleBBiuCefaAKNe5Uf1QASC9TzIiHknl2+sK9lOFZ+XZJ41HCU2sMvNBu1EHuBPNRIHodCEHdXHyRqBaC+vgWO6RcTWU4K5ZctBKmElAYst7FFCuzM+liUcGp3I1a7wxOJTPraxeFw8z69rYFiNMOng/HkV/G/VUQXzWalC5gtjaR35dMp35Mf1lMlGnWhy/qdLr0NVdl69qUDKt+kCG9+kiXO7Eq5PTbV+tj4AxBzxE1DroAh0jTPFLb7p1205+OQqqrCEq6tzpGHKTFLoyHZCVoxdQvxgFNX6+fNi3+MfbDfLle7msQAwOuaUl6rxcb2JjdgRQQUd4/GQbvKeLjFRIr7OtcVHWm3251jqRLBgFJcQ235SFgdjLnKATqN4BRe0WLyYOMuMQEmfQXaebjzMo7L2JMJeOar9QutuV+Acle7kJZZU4N1XPiUmborUksAcrmLGXvQITn1QLmadou0jX/oov+lkrKDIFTJC5MIutVBNmExS6FqW978viF1ZNgRQxG5OULHoT5tgfyjrl2u74VFf0ttbLC/JSsi1k8me2LA2vi2Sx7DNOzd6fLx0f8+mYmz2VTRw6fnoFh99d8HktPUNyKcGNZyZpsfkkhFSFV/U88tZ9gROWayLbRXS6g801Mi0tBg0RJp/Flo9ZX9Y3qKVWLCDZT6t3l1NR2npkGmi16yqslXSs9hadIvd6lxyYqyW6cskuJjsacHPOCyvz1xZFH6txtzmb46UrKUU7Cjo/09Kmtb740rXzhH/0nPuvJUjlk0UN77LqzvnvVWAe2IJVEjsbhTspLw3Z1fmCQxMKvc3yPA36/KP2uk/wOlHmBnuX/eebQmI22PFOzskl1d0ScNItJsw5D6fkEhybxEY3oPWYG5y+Oitqj1dQy/TNKXeJHMP+MC1PxzvaE3jq/+cb0IwVBnMVblbaHCJM6JAllV/p3Z6/Ho3Ps4hDHRflKZjP2HyB5wvvTtYhX5XpDoA8s9e6TpDXYnoE+XLN4Thzu30GL3WBeI7koYuNEpRhD5++oT2CElpEqo0v/TFKGSmnV+qohWTL8I4WnHSZeKDLC5alqIMYgRkN6qUlVJLzILOFzeJcL9zeXsAeHemd3VZWe0OYiJRxVwBCYGHk6W7WA4pZ+Wq/C0JHaxNJhr9gx0kyFlMPBkwN/LEyUP+PxsqIuW+09f70qZdGE1r9bNjUSKmb53I6nqxwQhIwvpZZDGAOZjaxrfC8PE9rOOTkM3v6zsSWgjl4EJMPwJubHJb63w5hvW2DwS4h3t7lduTab9ykKInvfBsaWxLuBhJuX+fesGTM0KGXs=|BXz0QzgtArYQXICHbYvGqOeFVi9YGZRP0MASNlVwzzY=", | ||
"providerOrganizations": [], | ||
"providers": [], | ||
"securityStamp": "aa485463-c258-40b5-b2cf-bf22bf705258", | ||
"twoFactorEnabled": false, | ||
"usesKeyConnector": false | ||
} |
Oops, something went wrong.