195 lines
4.7 KiB
Go
195 lines
4.7 KiB
Go
package jess
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Keywords and Prefixes for the export text format.
|
|
const (
|
|
ExportSenderKeyword = "sender"
|
|
ExportSenderPrefix = "sender:"
|
|
|
|
ExportRecipientKeyword = "recipient"
|
|
ExportRecipientPrefix = "recipient:"
|
|
|
|
ExportKeyKeyword = "secret"
|
|
ExportKeyPrefix = "secret:"
|
|
|
|
ExportEnvelopeKeyword = "envelope"
|
|
ExportEnvelopePrefix = "envelope:"
|
|
)
|
|
|
|
// Export exports the public part of a signet in text format.
|
|
func (signet *Signet) Export(short bool) (textFormat string, err error) {
|
|
// Make public if needed.
|
|
if !signet.Public {
|
|
signet, err = signet.AsRecipient()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
// Transform to text format.
|
|
return signet.toTextFormat(short)
|
|
}
|
|
|
|
// Backup exports the private part of a signet in text format.
|
|
func (signet *Signet) Backup(short bool) (textFormat string, err error) {
|
|
// Abprt if public.
|
|
if signet.Public {
|
|
return "", errors.New("cannot backup (only export) a recipient")
|
|
}
|
|
|
|
// Transform to text format.
|
|
return signet.toTextFormat(short)
|
|
}
|
|
|
|
func (signet *Signet) toTextFormat(short bool) (textFormat string, err error) {
|
|
// Serialize to base58.
|
|
base58data, err := signet.ToBase58()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Define keywords.
|
|
var keyword, typeComment string
|
|
switch {
|
|
case signet.Scheme == SignetSchemePassword:
|
|
return "", errors.New("cannot backup or export passwords")
|
|
case signet.Scheme == SignetSchemeKey:
|
|
// Check if the signet is marked as "public".
|
|
if signet.Public {
|
|
return "", errors.New("cannot export keys")
|
|
}
|
|
keyword = ExportKeyKeyword
|
|
typeComment = "symmetric-key"
|
|
case signet.Public:
|
|
keyword = ExportRecipientKeyword
|
|
typeComment = fmt.Sprintf(
|
|
"public-%s-key", toTextFormatString(signet.Scheme),
|
|
)
|
|
default:
|
|
keyword = ExportSenderKeyword
|
|
typeComment = fmt.Sprintf(
|
|
"private-%s-key", toTextFormatString(signet.Scheme),
|
|
)
|
|
}
|
|
|
|
// Transform to text format.
|
|
if short {
|
|
return fmt.Sprintf(
|
|
"%s:%s",
|
|
keyword,
|
|
base58data,
|
|
), nil
|
|
}
|
|
return fmt.Sprintf(
|
|
"%s:%s:%s:%s",
|
|
keyword,
|
|
typeComment,
|
|
toTextFormatString(signet.Info.Name),
|
|
base58data,
|
|
), nil
|
|
}
|
|
|
|
// Export exports the envelope in text format.
|
|
func (e *Envelope) Export(short bool) (textFormat string, err error) {
|
|
// Remove and key data.
|
|
e.CleanSignets()
|
|
|
|
// Serialize to base58.
|
|
base58data, err := e.ToBase58()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Transform to text format.
|
|
if short {
|
|
return fmt.Sprintf(
|
|
"%s:%s",
|
|
ExportEnvelopeKeyword,
|
|
base58data,
|
|
), nil
|
|
}
|
|
return fmt.Sprintf(
|
|
"%s:%s:%s:%s",
|
|
ExportEnvelopeKeyword,
|
|
e.SuiteID,
|
|
e.Name,
|
|
base58data,
|
|
), nil
|
|
}
|
|
|
|
// KeyFromTextFormat loads a secret key from the text format.
|
|
func KeyFromTextFormat(textFormat string) (*Signet, error) {
|
|
// Check the identifier.
|
|
if !strings.HasPrefix(textFormat, ExportKeyPrefix) {
|
|
return nil, errors.New("not a secret")
|
|
}
|
|
|
|
// Parse the data section.
|
|
splitted := strings.Split(textFormat, ":")
|
|
if len(splitted) < 2 {
|
|
return nil, errors.New("invalid format")
|
|
}
|
|
return SignetFromBase58(splitted[len(splitted)-1])
|
|
}
|
|
|
|
// SenderFromTextFormat loads a sender (private key) from the text format.
|
|
func SenderFromTextFormat(textFormat string) (*Signet, error) {
|
|
// Check the identifier.
|
|
if !strings.HasPrefix(textFormat, ExportSenderPrefix) {
|
|
return nil, errors.New("not a sender")
|
|
}
|
|
|
|
// Parse the data section.
|
|
splitted := strings.Split(textFormat, ":")
|
|
if len(splitted) < 2 {
|
|
return nil, errors.New("invalid format")
|
|
}
|
|
return SignetFromBase58(splitted[len(splitted)-1])
|
|
}
|
|
|
|
// RecipientFromTextFormat loads a recipient (public key) from the text format.
|
|
func RecipientFromTextFormat(textFormat string) (*Signet, error) {
|
|
// Check the identifier.
|
|
if !strings.HasPrefix(textFormat, ExportRecipientPrefix) {
|
|
return nil, errors.New("not a recipient")
|
|
}
|
|
|
|
// Parse the data section.
|
|
splitted := strings.Split(textFormat, ":")
|
|
if len(splitted) < 2 {
|
|
return nil, errors.New("invalid format")
|
|
}
|
|
return SignetFromBase58(splitted[len(splitted)-1])
|
|
}
|
|
|
|
// EnvelopeFromTextFormat loads an envelope from the text format.
|
|
func EnvelopeFromTextFormat(textFormat string) (*Envelope, error) {
|
|
// Check the identifier.
|
|
if !strings.HasPrefix(textFormat, ExportEnvelopePrefix) {
|
|
return nil, errors.New("not an envelope")
|
|
}
|
|
|
|
// Parse the data section.
|
|
splitted := strings.Split(textFormat, ":")
|
|
if len(splitted) < 2 {
|
|
return nil, errors.New("invalid format")
|
|
}
|
|
return EnvelopeFromBase58(splitted[len(splitted)-1])
|
|
}
|
|
|
|
var replaceForTextFormatMatcher = regexp.MustCompile(`[^A-Za-z0-9]+`)
|
|
|
|
// toTextFormatString makes a string compatible with the text format.
|
|
func toTextFormatString(s string) string {
|
|
return strings.ToLower(
|
|
strings.Trim(
|
|
replaceForTextFormatMatcher.ReplaceAllString(s, "-"), "-",
|
|
),
|
|
)
|
|
}
|