mirror of
https://github.com/passbolt/go-passbolt.git
synced 2025-05-11 02:18:20 +00:00
store userprivatekey in clients as crypto.key instead of armor
This commit is contained in:
parent
c7a0de783d
commit
118dd9624b
4 changed files with 21 additions and 67 deletions
|
@ -30,14 +30,7 @@ func (c *Client) CheckSession(ctx context.Context) bool {
|
||||||
func (c *Client) Login(ctx context.Context) error {
|
func (c *Client) Login(ctx context.Context) error {
|
||||||
c.csrfToken = http.Cookie{}
|
c.csrfToken = http.Cookie{}
|
||||||
|
|
||||||
privateKey, err := c.getPrivateKey(c.userPrivateKey, c.userPassword)
|
data := Login{&GPGAuth{KeyID: c.userPrivateKey.GetFingerprint()}}
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Parsing User Private Key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer privateKey.ClearPrivateParams()
|
|
||||||
|
|
||||||
data := Login{&GPGAuth{KeyID: privateKey.GetFingerprint()}}
|
|
||||||
|
|
||||||
res, _, err := c.DoCustomRequestAndReturnRawResponse(ctx, "POST", "/auth/login.json", "v2", data, nil)
|
res, _, err := c.DoCustomRequestAndReturnRawResponse(ctx, "POST", "/auth/login.json", "v2", data, nil)
|
||||||
if err != nil && !strings.Contains(err.Error(), "Error API JSON Response Status: Message: The authentication failed.") {
|
if err != nil && !strings.Contains(err.Error(), "Error API JSON Response Status: Message: The authentication failed.") {
|
||||||
|
|
|
@ -26,8 +26,7 @@ type Client struct {
|
||||||
|
|
||||||
// userPublicKey has been removed since it can be gotten from the private userPrivateKey
|
// userPublicKey has been removed since it can be gotten from the private userPrivateKey
|
||||||
|
|
||||||
userPassword []byte
|
userPrivateKey *crypto.Key
|
||||||
userPrivateKey string
|
|
||||||
userID string
|
userID string
|
||||||
|
|
||||||
// Server Settings Determining which Resource Types we can use
|
// Server Settings Determining which Resource Types we can use
|
||||||
|
@ -71,23 +70,13 @@ func NewClient(httpClient *http.Client, UserAgent, BaseURL, UserPrivateKey, User
|
||||||
|
|
||||||
pgp := crypto.PGP()
|
pgp := crypto.PGP()
|
||||||
|
|
||||||
// Verify that the Given Privatekey and Password are valid and work Together if we were provieded one
|
var unlockedKey *crypto.Key = nil
|
||||||
if UserPrivateKey != "" {
|
if UserPrivateKey != "" {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(UserPrivateKey)
|
key, err := GetPrivateKeyFromArmor(UserPrivateKey, []byte(UserPassword))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Unable to Create Key From UserPrivateKey string: %w", err)
|
return nil, fmt.Errorf("Get Private Key: %w", err)
|
||||||
}
|
}
|
||||||
unlockedKeyObj, err := privateKeyObj.Unlock([]byte(UserPassword))
|
unlockedKey = key
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Unable to Unlock UserPrivateKey using UserPassword: %w", err)
|
|
||||||
}
|
|
||||||
privateKeyRing, err := crypto.NewKeyRing(unlockedKeyObj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Unable to Create a new Key Ring using the unlocked UserPrivateKey: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup Secrets
|
|
||||||
privateKeyRing.ClearPrivateParams()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Client Object
|
// Create Client Object
|
||||||
|
@ -95,8 +84,7 @@ func NewClient(httpClient *http.Client, UserAgent, BaseURL, UserPrivateKey, User
|
||||||
httpClient: httpClient,
|
httpClient: httpClient,
|
||||||
baseURL: u,
|
baseURL: u,
|
||||||
userAgent: UserAgent,
|
userAgent: UserAgent,
|
||||||
userPassword: []byte(UserPassword),
|
userPrivateKey: unlockedKey,
|
||||||
userPrivateKey: UserPrivateKey,
|
|
||||||
pgp: pgp,
|
pgp: pgp,
|
||||||
}
|
}
|
||||||
return c, err
|
return c, err
|
||||||
|
@ -207,11 +195,11 @@ func (c *Client) GetPublicKey(ctx context.Context) (string, string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lets get the actual Fingerprint instead of trusting the Server
|
// Lets get the actual Fingerprint instead of trusting the Server
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(c.userPrivateKey)
|
serverKey, err := crypto.NewKeyFromArmored(body.Keydata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("Parsing Server Key: %w", err)
|
return "", "", fmt.Errorf("Parsing Server Key: %w", err)
|
||||||
}
|
}
|
||||||
return body.Keydata, privateKeyObj.GetFingerprint(), nil
|
return body.Keydata, serverKey.GetFingerprint(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setMetadataTypeSettings Gets and configures the Client to use the Types the Server wants us to use
|
// setMetadataTypeSettings Gets and configures the Client to use the Types the Server wants us to use
|
||||||
|
|
|
@ -8,14 +8,7 @@ import (
|
||||||
|
|
||||||
// EncryptMessage encrypts a message using the users public key and then signes the message using the users private key
|
// EncryptMessage encrypts a message using the users public key and then signes the message using the users private key
|
||||||
func (c *Client) EncryptMessage(message string) (string, error) {
|
func (c *Client) EncryptMessage(message string) (string, error) {
|
||||||
key, err := c.getPrivateKey(c.userPrivateKey, c.userPassword)
|
encHandle, err := c.pgp.Encryption().SigningKey(c.userPrivateKey).Recipient(c.userPrivateKey).New()
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("Get Private Key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer key.ClearPrivateParams()
|
|
||||||
|
|
||||||
encHandle, err := c.pgp.Encryption().SigningKey(key).Recipient(key).New()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("New Encryptor: %w", err)
|
return "", fmt.Errorf("New Encryptor: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -36,19 +29,12 @@ func (c *Client) EncryptMessage(message string) (string, error) {
|
||||||
|
|
||||||
// EncryptMessageWithPublicKey encrypts a message using the provided public key and then signes the message using the users private key
|
// EncryptMessageWithPublicKey encrypts a message using the provided public key and then signes the message using the users private key
|
||||||
func (c *Client) EncryptMessageWithPublicKey(publickey, message string) (string, error) {
|
func (c *Client) EncryptMessageWithPublicKey(publickey, message string) (string, error) {
|
||||||
key, err := c.getPrivateKey(c.userPrivateKey, c.userPassword)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("Get Private Key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer key.ClearPrivateParams()
|
|
||||||
|
|
||||||
publicKey, err := crypto.NewKeyFromArmored(publickey)
|
publicKey, err := crypto.NewKeyFromArmored(publickey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Get Public Key: %w", err)
|
return "", fmt.Errorf("Get Public Key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
encHandle, err := c.pgp.Encryption().SigningKey(key).Recipient(publicKey).New()
|
encHandle, err := c.pgp.Encryption().SigningKey(c.userPrivateKey).Recipient(publicKey).New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("New Encryptor: %w", err)
|
return "", fmt.Errorf("New Encryptor: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -68,29 +54,26 @@ func (c *Client) EncryptMessageWithPublicKey(publickey, message string) (string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptMessage decrypts a message using the users Private Key
|
// DecryptMessage decrypts a message using the users Private Key
|
||||||
func (c *Client) DecryptMessage(message string) (string, error) {
|
func (c *Client) DecryptMessage(armoredCiphertext string) (string, error) {
|
||||||
message, _, err := c.DecryptMessageWithPrivateKeyAndReturnSessionKey(c.userPrivateKey, c.userPassword, message)
|
message, _, err := c.DecryptMessageWithPrivateKeyAndReturnSessionKey(c.userPrivateKey, armoredCiphertext)
|
||||||
return message, err
|
return message, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptMessageWithPrivateKey Decrypts a Message using the Provided Private Key
|
// DecryptMessageWithPrivateKey Decrypts a Message using the Provided Private Key
|
||||||
// Returns the Session key so that it can be saved in a cache
|
// Returns the Session key so that it can be saved in a cache
|
||||||
func (c *Client) DecryptMessageWithPrivateKeyAndReturnSessionKey(privateKey string, passphrase []byte, ciphertextArmored string) (string, *crypto.SessionKey, error) {
|
func (c *Client) DecryptMessageWithPrivateKeyAndReturnSessionKey(privateKey *crypto.Key, armoredCiphertext string) (string, *crypto.SessionKey, error) {
|
||||||
key, err := c.getPrivateKey(privateKey, passphrase)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, fmt.Errorf("Get Private Key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer key.ClearPrivateParams()
|
decHandle, err := c.pgp.Decryption().
|
||||||
|
DecryptionKey(privateKey).
|
||||||
decHandle, err := c.pgp.Decryption().DecryptionKey(key).RetrieveSessionKey().New()
|
RetrieveSessionKey().
|
||||||
|
New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("New Decryptor: %w", err)
|
return "", nil, fmt.Errorf("New Decryptor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer decHandle.ClearPrivateParams()
|
defer decHandle.ClearPrivateParams()
|
||||||
|
|
||||||
res, err := decHandle.Decrypt([]byte(ciphertextArmored), crypto.Armor)
|
res, err := decHandle.Decrypt([]byte(armoredCiphertext), crypto.Armor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("Decrypt: %w", err)
|
return "", nil, fmt.Errorf("Decrypt: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -98,11 +81,7 @@ func (c *Client) DecryptMessageWithPrivateKeyAndReturnSessionKey(privateKey stri
|
||||||
return res.String(), res.SessionKey(), nil
|
return res.String(), res.SessionKey(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) getPrivateKey(privateKey string, passphrase []byte) (*crypto.Key, error) {
|
func GetPrivateKeyFromArmor(privateKey string, passphrase []byte) (*crypto.Key, error) {
|
||||||
if c.userPrivateKey == "" {
|
|
||||||
return nil, fmt.Errorf("Client has no Private Key")
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := crypto.NewKeyFromArmored(privateKey)
|
key, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Key From Armored: %w", err)
|
return nil, fmt.Errorf("Key From Armored: %w", err)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v3/crypto"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,15 +43,10 @@ func (c *Client) SetupServerVerification(ctx context.Context) (string, string, e
|
||||||
|
|
||||||
// VerifyServer verifys that the Server is still the same one as during the Setup, Only works before login
|
// VerifyServer verifys that the Server is still the same one as during the Setup, Only works before login
|
||||||
func (c *Client) VerifyServer(ctx context.Context, token, encToken string) error {
|
func (c *Client) VerifyServer(ctx context.Context, token, encToken string) error {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(c.userPrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Parsing User Private Key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := GPGVerifyContainer{
|
data := GPGVerifyContainer{
|
||||||
Req: GPGVerify{
|
Req: GPGVerify{
|
||||||
Token: encToken,
|
Token: encToken,
|
||||||
KeyID: privateKeyObj.GetFingerprint(),
|
KeyID: c.userPrivateKey.GetFingerprint(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
raw, _, err := c.DoCustomRequestAndReturnRawResponse(ctx, "POST", "/auth/verify.json", "v2", data, nil)
|
raw, _, err := c.DoCustomRequestAndReturnRawResponse(ctx, "POST", "/auth/verify.json", "v2", data, nil)
|
||||||
|
|
Loading…
Add table
Reference in a new issue