add private key handling
This also contains a couple fixes to the subject part.
This commit is contained in:
parent
b9c2539073
commit
bc8e1353af
|
@ -40,28 +40,16 @@ func main() {
|
|||
err = setSubject(args, client)
|
||||
case `show-subj`:
|
||||
err = showSubject(args, client)
|
||||
// case `list`:
|
||||
// err = listDescription(args, client)
|
||||
// case `create-file`:
|
||||
// err = createFile(args, client)
|
||||
// case `list-files`:
|
||||
// err = listFile(args, client)
|
||||
// case `delete-file`:
|
||||
// err = deleteFile(args, client)
|
||||
// case `create-private-key`:
|
||||
// err = createPrivateKey(args, client)
|
||||
// case `get-private-key`:
|
||||
// err = getPrivateKey(args, client)
|
||||
// case `list-private-keys`:
|
||||
// err = listPrivateKey(args, client)
|
||||
// case `delete-private-key`:
|
||||
// err = deletePrivateKey(args, client)
|
||||
// case `create-public-key`:
|
||||
// err = createPublicKey(args, client)
|
||||
// case `list-public-keys`:
|
||||
// err = listPublicKey(args, client)
|
||||
// case `delete-public-key`:
|
||||
// err = deletePublicKey(args, client)
|
||||
case `create-private`:
|
||||
err = createPrivateKey(args, client)
|
||||
case `delete-private`:
|
||||
err = deletePrivateKey(args, client)
|
||||
case `list-private`:
|
||||
err = listPrivateKey(args, client)
|
||||
case `set-private`:
|
||||
err = setPrivateKey(args, client)
|
||||
case `show-private`:
|
||||
err = showPrivateKey(args, client)
|
||||
default:
|
||||
fmt.Printf("unknown subcommand '%s'\n", cmd)
|
||||
printCommands()
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
"github.com/pkg/errors"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func createPrivateKey(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("create-private", flag.ExitOnError)
|
||||
fs.Usage = func() {
|
||||
fmt.Printf("Usage of %s:\n", "pkiadm create-private")
|
||||
fmt.Println(`
|
||||
Create a new private key for different use cases. The supported types are rsa,
|
||||
ecdsa and ed25519. Please keep in mind, that ed25519 is currently not supported
|
||||
for certificate generation.
|
||||
`)
|
||||
fs.PrintDefaults()
|
||||
}
|
||||
pk := pkiadm.PrivateKey{}
|
||||
fs.StringVar(&pk.ID, "id", "", "set the unique id for the new private key")
|
||||
var pkType = fs.String("type", "rsa", "set the type of the private key (rsa, ecdsa, ed25519)")
|
||||
fs.UintVar(&pk.Bits, "bits", 2048, "set the number of bits to use. For rsa it can be 1024 up to 32768, for ecdsa 224, 256, 384, 521. Ed25519 is set to 256 by default.")
|
||||
fs.Parse(args)
|
||||
|
||||
pkT, err := pkiadm.StringToPrivateKeyType(*pkType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk.Type = pkT
|
||||
if err := client.CreatePrivateKey(pk); err != nil {
|
||||
return errors.Wrap(err, "could not create private key")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func setPrivateKey(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("set-private", flag.ExitOnError)
|
||||
pk := pkiadm.PrivateKey{}
|
||||
fs.StringVar(&pk.ID, "id", "", "set the id of the private key to change")
|
||||
var pkType = fs.String("type", "rsa", "set the type of the private key (rsa, ecdsa, ed25519)")
|
||||
fs.UintVar(&pk.Bits, "bits", 2048, "set the number of bits to use. For rsa it can be 1024 up to 32768, for ecdsa 224, 256, 384, 521. Ed25519 is set to 256 by default.")
|
||||
fs.Parse(args)
|
||||
|
||||
pkT, err := pkiadm.StringToPrivateKeyType(*pkType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk.Type = pkT
|
||||
|
||||
fieldList := []string{}
|
||||
for _, field := range []string{"type", "bits"} {
|
||||
flag := fs.Lookup(field)
|
||||
if flag.Changed {
|
||||
fieldList = append(fieldList, field)
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.SetPrivateKey(pk, fieldList); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func deletePrivateKey(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("delete-private", flag.ExitOnError)
|
||||
var id = fs.String("id", "", "set the id of the private key to delete")
|
||||
fs.Parse(args)
|
||||
|
||||
if err := client.DeletePrivateKey(*id); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func listPrivateKey(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("list-private", flag.ExitOnError)
|
||||
fs.Parse(args)
|
||||
|
||||
pks, err := client.ListPrivateKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(pks) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := tabwriter.NewWriter(os.Stdout, 2, 2, 1, ' ', tabwriter.AlignRight)
|
||||
fmt.Fprintf(out, "%s\t%s\t%s\t\n", "id", "type", "bits")
|
||||
for _, pk := range pks {
|
||||
fmt.Fprintf(out, "%s\t%s\t%d\t\n", pk.ID, pk.Type.String(), pk.Bits)
|
||||
}
|
||||
out.Flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
func showPrivateKey(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("show-private", flag.ExitOnError)
|
||||
var id = fs.String("id", "", "set the id of the private key to show")
|
||||
fs.Parse(args)
|
||||
|
||||
pk, err := client.ShowPrivateKey(*id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out := tabwriter.NewWriter(os.Stdout, 2, 2, 1, ' ', tabwriter.AlignRight)
|
||||
fmt.Fprintf(out, "ID:\t%s\t\n", pk.ID)
|
||||
fmt.Fprintf(out, "type:\t%s\t\n", pk.Type.String())
|
||||
fmt.Fprintf(out, "bits:\t%d\t\n", pk.Bits)
|
||||
fmt.Fprintf(out, "checksum:\t%s\t\n", base64.StdEncoding.EncodeToString(pk.Checksum))
|
||||
out.Flush()
|
||||
return nil
|
||||
}
|
|
@ -32,7 +32,6 @@ In most cases only the common name, organization name and the country is provide
|
|||
}
|
||||
|
||||
if err := client.CreateSubject(subj); err != nil {
|
||||
fmt.Println("got an error")
|
||||
return errors.Wrap(err, "could not create new subject")
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -6,12 +6,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/gibheer/pki"
|
||||
)
|
||||
|
||||
const (
|
||||
PKTRSA PrivateKeyType = iota
|
||||
PKTECDSA
|
||||
PKTED25519
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -23,24 +18,23 @@ const (
|
|||
type (
|
||||
PrivateKey struct {
|
||||
ID string
|
||||
PKType PrivateKeyType
|
||||
Length uint
|
||||
PKType pkiadm.PrivateKeyType
|
||||
Bits uint
|
||||
Key []byte
|
||||
}
|
||||
PrivateKeyType uint
|
||||
)
|
||||
|
||||
func NewPrivateKey(id string, pkType PrivateKeyType, length uint) (*PrivateKey, error) {
|
||||
func NewPrivateKey(id string, pkType pkiadm.PrivateKeyType, bits uint) (*PrivateKey, error) {
|
||||
if id == "" {
|
||||
return nil, ENoIDGiven
|
||||
}
|
||||
if err := verifyPK(pkType, length); err != nil {
|
||||
if err := verifyPK(pkType, bits); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pk := PrivateKey{
|
||||
ID: id,
|
||||
PKType: pkType,
|
||||
Length: length,
|
||||
Bits: bits,
|
||||
}
|
||||
return &pk, nil
|
||||
}
|
||||
|
@ -67,13 +61,13 @@ func (p *PrivateKey) Refresh(_ *Storage) error {
|
|||
err error
|
||||
)
|
||||
switch p.PKType {
|
||||
case PKTRSA:
|
||||
key, err = pki.NewPrivateKeyRsa(int(p.Length))
|
||||
case PKTED25519:
|
||||
case pkiadm.PKTRSA:
|
||||
key, err = pki.NewPrivateKeyRsa(int(p.Bits))
|
||||
case pkiadm.PKTED25519:
|
||||
key, err = pki.NewPrivateKeyEd25519()
|
||||
case PKTECDSA:
|
||||
case pkiadm.PKTECDSA:
|
||||
var curve elliptic.Curve
|
||||
switch p.Length {
|
||||
switch p.Bits {
|
||||
case 224:
|
||||
curve = elliptic.P224()
|
||||
case 256:
|
||||
|
@ -120,20 +114,20 @@ func (p *PrivateKey) GetKey() (pki.PrivateKey, error) {
|
|||
return key, nil
|
||||
}
|
||||
|
||||
func verifyPK(pkType PrivateKeyType, length uint) error {
|
||||
func verifyPK(pkType pkiadm.PrivateKeyType, bits uint) error {
|
||||
switch pkType {
|
||||
case PKTRSA:
|
||||
if length < 1024 || length > 32768 {
|
||||
case pkiadm.PKTRSA:
|
||||
if bits < 1024 || bits > 32768 {
|
||||
return ELengthOutOfBounds
|
||||
}
|
||||
case PKTECDSA:
|
||||
switch length {
|
||||
case pkiadm.PKTECDSA:
|
||||
switch bits {
|
||||
case 224, 256, 384, 521:
|
||||
default:
|
||||
return EWrongKeyLength
|
||||
}
|
||||
case PKTED25519:
|
||||
if length != 256 {
|
||||
case pkiadm.PKTED25519:
|
||||
if bits != 256 {
|
||||
return EWrongKeyLengthED25519
|
||||
}
|
||||
default:
|
||||
|
@ -142,9 +136,92 @@ func verifyPK(pkType PrivateKeyType, length uint) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//func (p *PrivateKey) MarshalJSON() ([]byte, error) {
|
||||
// return json.Marshal(*p)
|
||||
//}
|
||||
//func (p *PrivateKey) UnmarshalJSON(raw []byte) error {
|
||||
// return json.Unmarshal(raw, p)
|
||||
//}
|
||||
func (s *Server) CreatePrivateKey(inPk pkiadm.PrivateKey, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := NewPrivateKey(inPk.ID, inPk.Type, inPk.Bits)
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not create new private key '%s'", inPk.ID)
|
||||
return nil
|
||||
}
|
||||
if err := s.storage.AddPrivateKey(pk); err != nil {
|
||||
res.SetError(err, "Could not add private key '%s'", inPk.ID)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s *Server) SetPrivateKey(changeset pkiadm.PrivateKeyChange, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: changeset.PrivateKey.ID, Type: RTPrivateKey})
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not find private key '%s'", changeset.PrivateKey.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, field := range changeset.FieldList {
|
||||
switch field {
|
||||
case "type":
|
||||
pk.PKType = changeset.PrivateKey.Type
|
||||
case "bits":
|
||||
pk.Bits = changeset.PrivateKey.Bits
|
||||
default:
|
||||
res.SetError(fmt.Errorf("unknown field"), "unknown field '%s'", field)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := s.storage.Update(ResourceName{ID: pk.ID, Type: RTPrivateKey}); err != nil {
|
||||
res.SetError(err, "Could not update private key '%s'", changeset.PrivateKey.ID)
|
||||
return nil
|
||||
}
|
||||
return s.store(res)
|
||||
}
|
||||
func (s *Server) DeletePrivateKey(inPk pkiadm.ResourceName, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: inPk.ID, Type: RTPrivateKey})
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not find private key '%s'", inPk.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.storage.Remove(pk); err != nil {
|
||||
res.SetError(err, "Could not remove private key '%s'", pk.ID)
|
||||
return nil
|
||||
}
|
||||
return s.store(res)
|
||||
}
|
||||
func (s *Server) ShowPrivateKey(inPk pkiadm.ResourceName, res *pkiadm.ResultPrivateKey) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: inPk.ID, Type: RTPrivateKey})
|
||||
if err != nil {
|
||||
res.Result.SetError(err, "Could not find private key '%s'", inPk.ID)
|
||||
return nil
|
||||
}
|
||||
res.PrivateKeys = []pkiadm.PrivateKey{pkiadm.PrivateKey{
|
||||
ID: pk.ID,
|
||||
Type: pk.PKType,
|
||||
Bits: pk.Bits,
|
||||
Checksum: pk.Checksum(),
|
||||
}}
|
||||
return nil
|
||||
}
|
||||
func (s *Server) ListPrivateKey(filter pkiadm.Filter, res *pkiadm.ResultPrivateKey) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
for _, pk := range s.storage.PrivateKeys {
|
||||
res.PrivateKeys = append(res.PrivateKeys, pkiadm.PrivateKey{
|
||||
ID: pk.ID,
|
||||
Type: pk.PKType,
|
||||
Bits: pk.Bits,
|
||||
Checksum: pk.Checksum(),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"crypto/x509/pkix"
|
||||
"fmt"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
@ -90,10 +91,13 @@ func (s *Server) SetSubject(changeset pkiadm.SubjectChange, res *pkiadm.Result)
|
|||
subj.Data.StreetAddress = changes.StreetAddress
|
||||
case "code":
|
||||
subj.Data.PostalCode = changes.PostalCode
|
||||
default:
|
||||
res.SetError(fmt.Errorf("unknown field"), "unknown field '%s'", field)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := s.storage.Update(ResourceName{ID: subj.ID, Type: RTSubject}); err != nil {
|
||||
res.SetError(err, "Could update resource '%s'", changeset.Subject.ID)
|
||||
res.SetError(err, "Could not update subject '%s'", changeset.Subject.ID)
|
||||
return nil
|
||||
}
|
||||
return s.store(res)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package pkiadm
|
||||
|
||||
const (
|
||||
PKTRSA PrivateKeyType = iota
|
||||
PKTECDSA
|
||||
PKTED25519
|
||||
PKTUnknown
|
||||
)
|
||||
|
||||
type (
|
||||
PrivateKey struct {
|
||||
ID string
|
||||
Type PrivateKeyType
|
||||
Bits uint
|
||||
Checksum []byte // This field is only set by the server
|
||||
}
|
||||
PrivateKeyChange struct {
|
||||
PrivateKey PrivateKey
|
||||
FieldList []string
|
||||
}
|
||||
ResultPrivateKey struct {
|
||||
Result Result
|
||||
PrivateKeys []PrivateKey
|
||||
}
|
||||
PrivateKeyType uint
|
||||
)
|
||||
|
||||
// CreatePrivateKey sends a RPC request to create a new private key.
|
||||
func (c *Client) CreatePrivateKey(pk PrivateKey) error {
|
||||
return c.exec("CreatePrivateKey", pk)
|
||||
}
|
||||
func (c *Client) SetPrivateKey(pk PrivateKey, fieldList []string) error {
|
||||
changeset := PrivateKeyChange{pk, fieldList}
|
||||
return c.exec("SetPrivateKey", changeset)
|
||||
}
|
||||
func (c *Client) DeletePrivateKey(id string) error {
|
||||
pk := ResourceName{ID: id, Type: RTPrivateKey}
|
||||
return c.exec("DeletePrivateKey", pk)
|
||||
}
|
||||
func (c *Client) ListPrivateKey() ([]PrivateKey, error) {
|
||||
result := &ResultPrivateKey{}
|
||||
if err := c.query("ListPrivateKey", Filter{}, result); err != nil {
|
||||
return []PrivateKey{}, err
|
||||
}
|
||||
if result.Result.HasError {
|
||||
return []PrivateKey{}, result.Result.Error
|
||||
}
|
||||
return result.PrivateKeys, nil
|
||||
}
|
||||
func (c *Client) ShowPrivateKey(id string) (PrivateKey, error) {
|
||||
pk := ResourceName{ID: id, Type: RTPrivateKey}
|
||||
result := &ResultPrivateKey{}
|
||||
if err := c.query("ShowPrivateKey", pk, result); err != nil {
|
||||
return PrivateKey{}, err
|
||||
}
|
||||
if result.Result.HasError {
|
||||
return PrivateKey{}, result.Result.Error
|
||||
}
|
||||
for _, privateKey := range result.PrivateKeys {
|
||||
return privateKey, nil
|
||||
}
|
||||
return PrivateKey{}, nil
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Code generated by "stringer -type PrivateKeyType"; DO NOT EDIT
|
||||
|
||||
package pkiadm
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _PrivateKeyType_name = "rsaecdsaed25519"
|
||||
|
||||
var _PrivateKeyType_index = [...]uint8{0, 3, 8, 15}
|
||||
|
||||
func (i PrivateKeyType) String() string {
|
||||
if i >= PrivateKeyType(len(_PrivateKeyType_index)-1) {
|
||||
return fmt.Sprintf("PrivateKeyType(%d)", i)
|
||||
}
|
||||
return _PrivateKeyType_name[_PrivateKeyType_index[i]:_PrivateKeyType_index[i+1]]
|
||||
}
|
||||
|
||||
func StringToPrivateKeyType(t string) (PrivateKeyType, error) {
|
||||
switch t {
|
||||
case "rsa":
|
||||
return PKTRSA, nil
|
||||
case "ecdsa":
|
||||
return PKTECDSA, nil
|
||||
case "ed25519":
|
||||
return PKTED25519, nil
|
||||
default:
|
||||
return PKTUnknown, fmt.Errorf("unknown private key type")
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ func (c *Client) ShowSubject(id string) (Subject, error) {
|
|||
subj := ResourceName{ID: id, Type: RTSubject}
|
||||
result := &ResultSubjects{}
|
||||
if err := c.query("ShowSubject", subj, result); err != nil {
|
||||
return Subject{}, nil
|
||||
return Subject{}, err
|
||||
}
|
||||
if result.Result.HasError {
|
||||
return Subject{}, result.Result.Error
|
||||
|
|
Loading…
Reference in New Issue