func (c *Cert) String() string {
	return fmt.Sprintf("%s %s", ssh.CertAlgoECDSA256v01, base64.StdEncoding.EncodeToString(c.Certificate.Marshal()))
}
String will output the SSH certificate in a format that can be used
with an ssh client.
package sshcert
import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"encoding/base64"
	"encoding/binary"
	"encoding/hex"
	"encoding/pem"
	"errors"
	"fmt"
	"strings"
	"time"
	"golang.org/x/crypto/ssh"
)
const (
	caName         = "open-ssh-ca@ejj.io"
	hour           = time.Second * 3600
	allowableDrift = 60 * time.Second
	pemHeader      = "BEGIN SSHCERT PRIVATE KEY"
)
var (
	DefaultPermissions = ssh.Permissions{
		Extensions: map[string]string{
			"permit-pty":              "",
			"permit-user-rc":          "",
			"permit-port-forwarding":  "",
			"permit-agent-forwarding": "",
		},
	}
)
type CA struct {
	PrivateKey *ecdsa.PrivateKey
	customName string
}
type Cert struct {
	Certificate *ssh.Certificate
}
type SigningArguments struct {
	Principals  []string
	Permissions ssh.Permissions
	Duration    time.Duration
}
func NewCA() (CA, error) {
	key, err := createPrivateKey()
	return CA{
		PrivateKey: key,
		customName: caName,
	}, err
}
func (c *CA) SignCert(pub ssh.PublicKey, signArgs *SigningArguments) (*Cert, error) {
	cert := &ssh.Certificate{
		Key:      pub,
		Serial:   randomSerial(),
		CertType: ssh.UserCert,
		KeyId:    randomHex(),
		ValidAfter:      uint64(time.Now().Add(-allowableDrift).Unix()),
		ValidBefore:     uint64(time.Now().Add(signArgs.Duration).Unix()),
		ValidPrincipals: signArgs.Principals,
		Permissions:     signArgs.Permissions,
	}
	err := cert.SignCert(rand.Reader, c.Signer())
	if err != nil {
		return nil, err
	}
	return &Cert{Certificate: cert}, nil
}
func (c *CA) PrivateString() (string, error) {
	privDer, err := x509.MarshalECPrivateKey(c.PrivateKey)
	if err != nil {
		return "", err
	}
	privBlock := pem.Block{
		Type:    pemHeader,
		Headers: nil,
		Bytes:   privDer,
	}
	privatePEM := pem.EncodeToMemory(&privBlock)
	return string(privatePEM), nil
}
func (c *CA) ParsePrivateString(data []byte) error {
	block, _ := pem.Decode(data)
	return c.FromBytes(block.Bytes)
}
func (c *CA) Signer() ssh.Signer {
	signer, _ := ssh.NewSignerFromKey(c.PrivateKey)
	return signer
}
func (c *CA) String() string {
	return fmt.Sprintf("%s %s %s", c.Signer().PublicKey().Type(), base64.StdEncoding.EncodeToString(c.Signer().PublicKey().Marshal()), c.customName)
}
func (c *CA) Bytes() ([]byte, error) {
	return x509.MarshalECPrivateKey(c.PrivateKey)
}
func (c *CA) FromBytes(data []byte) error {
	priv, err := x509.ParseECPrivateKey(data)
	if err != nil {
		return err
	}
	c.PrivateKey = priv
	return nil
}
func (c *CA) SetName(name string) {
	c.customName = name
}