mirror of
https://github.com/versia-pub/versia-go.git
synced 2025-12-06 14:28:20 +01:00
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package lysand
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidPublicKeyType = errors.New("invalid public key type")
|
|
)
|
|
|
|
// PublicKey represents a public key for a user. For more information, see the [Spec].
|
|
//
|
|
// [Spec]: https://lysand.org/security/keys#public-key-cryptography
|
|
type PublicKey struct {
|
|
PublicKey SPKIPublicKey `json:"public_key"`
|
|
Actor *URL `json:"actor"`
|
|
}
|
|
|
|
// SPKIPublicKey is a type that represents a [ed25519.PublicKey] in the SPKI
|
|
// format.
|
|
type SPKIPublicKey ed25519.PublicKey
|
|
|
|
// UnmarshalJSON decodes the public key from a base64 encoded string and then unmarshals it from the SPKI form.
|
|
func (k *SPKIPublicKey) UnmarshalJSON(raw []byte) error {
|
|
rawStr := ""
|
|
if err := json.Unmarshal(raw, &rawStr); err != nil {
|
|
return err
|
|
}
|
|
|
|
raw, err := base64.StdEncoding.DecodeString(rawStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
parsed, err := x509.ParsePKIXPublicKey(raw)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
edKey, ok := parsed.(ed25519.PublicKey)
|
|
if !ok {
|
|
return ErrInvalidPublicKeyType
|
|
}
|
|
|
|
*k = SPKIPublicKey(edKey)
|
|
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON marshals the SPKI-encoded public key to a base64 encoded string.
|
|
func (k SPKIPublicKey) MarshalJSON() ([]byte, error) {
|
|
raw, err := x509.MarshalPKIXPublicKey(ed25519.PublicKey(k))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return json.Marshal(base64.StdEncoding.EncodeToString(raw))
|
|
}
|
|
|
|
func (k SPKIPublicKey) ToStd() ed25519.PublicKey {
|
|
return ed25519.PublicKey(k)
|
|
}
|