2024-02-04 19:34:09 +01:00
|
|
|
package bitwarden
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/sha256"
|
2024-02-04 19:56:36 +01:00
|
|
|
"encoding/base64"
|
2024-02-04 19:34:09 +01:00
|
|
|
"io"
|
2024-02-04 19:56:36 +01:00
|
|
|
"strings"
|
2024-02-04 19:34:09 +01:00
|
|
|
"time"
|
|
|
|
|
2024-05-04 01:06:24 +02:00
|
|
|
"github.com/quexten/goldwarden/cli/agent/bitwarden/crypto"
|
|
|
|
"github.com/quexten/goldwarden/cli/agent/config"
|
|
|
|
"github.com/quexten/goldwarden/cli/agent/vault"
|
2024-02-04 19:34:09 +01:00
|
|
|
"golang.org/x/crypto/hkdf"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SendFileMetadata struct {
|
|
|
|
FileName string `json:"fileName"`
|
|
|
|
Id string `json:"id"`
|
|
|
|
Size int `json:"size"`
|
|
|
|
SizeName string `json:"sizeName"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type SendTextMetadata struct {
|
|
|
|
Hidden bool `json:"hidden"`
|
|
|
|
Response *string `json:"response"`
|
|
|
|
Text string `json:"text"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type SendMetadata struct {
|
|
|
|
CreatorIdentifier string
|
|
|
|
ExpirationDate string
|
|
|
|
File SendFileMetadata
|
|
|
|
Id string
|
|
|
|
Name string
|
|
|
|
Object string
|
|
|
|
Text SendTextMetadata
|
|
|
|
Type int
|
|
|
|
}
|
|
|
|
|
|
|
|
type SendCreateRequest struct {
|
2024-02-04 19:56:36 +01:00
|
|
|
AccessCount *int `json:"accessCount"`
|
|
|
|
AccessId *string `json:"accessId"`
|
2024-02-04 19:34:09 +01:00
|
|
|
DeletionDate string `json:"deletionDate"`
|
|
|
|
Disabled bool `json:"disabled"`
|
|
|
|
ExpirationDate *string `json:"expirationDate"`
|
|
|
|
HideEmail bool `json:"hideEmail"`
|
|
|
|
Key string `json:"key"`
|
|
|
|
MaxAccessCount *int `json:"maxAccessCount"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Notes *string `json:"notes"`
|
|
|
|
Text SendTextMetadata `json:"text"`
|
|
|
|
Type int `json:"type"`
|
|
|
|
}
|
|
|
|
|
2024-02-04 19:56:36 +01:00
|
|
|
func CreateSend(ctx context.Context, cfg *config.Config, vault *vault.Vault, name string, text string) (string, error) {
|
2024-02-04 19:34:09 +01:00
|
|
|
timestampIn14Days := time.Now().AddDate(0, 0, 14)
|
|
|
|
timestampIn14DaysStr := timestampIn14Days.Format("2006-01-02T15:04:05Z")
|
|
|
|
|
|
|
|
// generate 32 byte key
|
|
|
|
sendSourceKey := make([]byte, 32)
|
|
|
|
_, err := io.ReadFull(rand.Reader, sendSourceKey)
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
encryptedSendSourceKey, err := crypto.EncryptWithToString(sendSourceKey, crypto.AesCbc256_HmacSha256_B64, vault.Keyring.GetAccountKey())
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sendUseKeyPairBytes := make([]byte, 64)
|
2024-03-03 01:38:11 +01:00
|
|
|
_, err = hkdf.New(sha256.New, sendSourceKey, []byte("bitwarden-send"), []byte("send")).Read(sendUseKeyPairBytes)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2024-02-04 19:34:09 +01:00
|
|
|
|
|
|
|
sendUseKeyPair, err := crypto.MemorySymmetricEncryptionKeyFromBytes(sendUseKeyPairBytes)
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
encryptedName, err := crypto.EncryptWithToString([]byte(name), crypto.AesCbc256_HmacSha256_B64, sendUseKeyPair)
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
encryptedText, err := crypto.EncryptWithToString([]byte(text), crypto.AesCbc256_HmacSha256_B64, sendUseKeyPair)
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sendRequest := SendCreateRequest{
|
|
|
|
DeletionDate: timestampIn14DaysStr,
|
|
|
|
Disabled: false,
|
|
|
|
HideEmail: false,
|
|
|
|
Key: encryptedSendSourceKey,
|
|
|
|
Name: encryptedName,
|
|
|
|
Text: SendTextMetadata{
|
|
|
|
Hidden: false,
|
|
|
|
Text: encryptedText,
|
|
|
|
},
|
|
|
|
Type: 0,
|
|
|
|
}
|
|
|
|
|
2024-02-04 19:56:36 +01:00
|
|
|
var result SendCreateRequest
|
2024-02-04 19:34:09 +01:00
|
|
|
err = authenticatedHTTPPost(ctx, cfg.ConfigFile.ApiUrl+"/sends", &result, sendRequest)
|
|
|
|
if err != nil {
|
2024-02-04 19:56:36 +01:00
|
|
|
return "", err
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|
|
|
|
|
2024-02-04 19:56:36 +01:00
|
|
|
return cfg.ConfigFile.VaultUrl + "/#/send/" + *result.AccessId + "/" + strings.ReplaceAll(base64.RawURLEncoding.EncodeToString(sendSourceKey), "+", "-"), nil
|
2024-02-04 19:34:09 +01:00
|
|
|
}
|