add public key support

This adds public key support. This also moves some of the type files
around or removes it, because they weren't used anymore.
This commit is contained in:
Gibheer 2017-06-03 21:56:32 +02:00
parent 92020d30b7
commit b9456bfd8b
5 changed files with 254 additions and 52 deletions

93
cmd/pkiadm/public_key.go Normal file
View File

@ -0,0 +1,93 @@
package main
import (
"encoding/base64"
"fmt"
"os"
"text/tabwriter"
"github.com/gibheer/pkiadm"
"github.com/pkg/errors"
flag "github.com/spf13/pflag"
)
func createPublicKey(args []string, client *pkiadm.Client) error {
fs := flag.NewFlagSet("pkiadm create-public", flag.ExitOnError)
id := fs.String("id", "", "the id to set for the public key")
pk := fs.String("private-key", "", "the id of the private key to use for public key creation")
fs.Parse(args)
pkName := pkiadm.ResourceName{ID: *pk, Type: pkiadm.RTPrivateKey}
if err := client.CreatePublicKey(
pkiadm.PublicKey{ID: *id, PrivateKey: pkName},
); err != nil {
return errors.Wrap(err, "Could not create public key")
}
return nil
}
func setPublicKey(args []string, client *pkiadm.Client) error {
fs := flag.NewFlagSet("pkiadm set-public", flag.ExitOnError)
id := fs.String("id", "", "the id of the public key to change")
pk := fs.String("private-key", "", "the id of the new private key to use for public key generation")
fs.Parse(args)
if !fs.Lookup("private-key").Changed {
return nil
}
pkName := pkiadm.ResourceName{ID: *pk, Type: pkiadm.RTPrivateKey}
if err := client.SetPublicKey(
pkiadm.PublicKey{ID: *id, PrivateKey: pkName},
[]string{"private-key"},
); err != nil {
return errors.Wrap(err, "Could not change public key")
}
return nil
}
func deletePublicKey(args []string, client *pkiadm.Client) error {
fs := flag.NewFlagSet("pkiadm delete-public", flag.ExitOnError)
id := fs.String("id", "", "the id of the public key to delete")
fs.Parse(args)
if err := client.DeletePublicKey(pkiadm.PublicKey{ID: *id}); err != nil {
return errors.Wrap(err, "Could not delete public key")
}
return nil
}
func listPublicKey(args []string, client *pkiadm.Client) error {
fs := flag.NewFlagSet("list-private", flag.ExitOnError)
fs.Parse(args)
pubs, err := client.ListPublicKey()
if err != nil {
return err
}
if len(pubs) == 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", "private-key")
for _, pub := range pubs {
fmt.Fprintf(out, "%s\t%s\t%s\t\n", pub.ID, pub.Type.String(), pub.PrivateKey)
}
out.Flush()
return nil
}
func showPublicKey(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)
pub, err := client.ShowPublicKey(*id)
if err != nil {
return err
}
out := tabwriter.NewWriter(os.Stdout, 2, 2, 1, ' ', tabwriter.AlignRight)
fmt.Fprintf(out, "ID:\t%s\t\n", pub.ID)
fmt.Fprintf(out, "type:\t%s\t\n", pub.Type.String())
fmt.Fprintf(out, "private:\t%s\t\n", pub.PrivateKey)
fmt.Fprintf(out, "checksum:\t%s\t\n", base64.StdEncoding.EncodeToString(pub.Checksum))
out.Flush()
return nil
}

View File

@ -2,26 +2,19 @@ package main
import (
"encoding/pem"
"fmt"
"github.com/gibheer/pkiadm"
)
const (
PUTRSA PublicKeyType = iota
PUTECDSA
PUTED25519
)
type (
PublicKey struct {
ID string
PrivateKey pkiadm.ResourceName
Type PublicKeyType // mark the type of the public key
Type pkiadm.PrivateKeyType // mark the type of the public key
Key []byte
}
PublicKeyType uint
)
func NewPublicKey(id string, pk pkiadm.ResourceName) (*PublicKey, error) {
@ -37,14 +30,11 @@ func (p *PublicKey) Name() pkiadm.ResourceName {
}
func (p *PublicKey) Refresh(lookup *Storage) error {
r, err := lookup.Get(p.PrivateKey)
pk, err := lookup.GetPrivateKey(p.PrivateKey)
if err != nil {
return err
}
pk, ok := r.(*PrivateKey)
if !ok {
return EUnknownType
}
p.Type = pk.PKType
privateKey, err := pk.GetKey()
if err != nil {
return err
@ -71,9 +61,98 @@ func (p *PublicKey) Checksum() []byte {
return Hash(p.Key)
}
//func (p *PublicKey) MarshalJSON() ([]byte, error) {
// return json.Marshal(*p)
//}
//func (p *PublicKey) UnmarshalJSON(raw []byte) error {
// return json.Unmarshal(raw, p)
//}
func (s *Server) CreatePublicKey(inPub pkiadm.PublicKey, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
pub, err := NewPublicKey(inPub.ID, inPub.PrivateKey)
if err != nil {
res.SetError(err, "Could not create public key '%s'", inPub.ID)
return nil
}
if err := s.storage.AddPublicKey(pub); err != nil {
res.SetError(err, "Could not add new public key '%s'", inPub.ID)
return nil
}
return s.store(res)
}
func (s *Server) SetPublicKey(inPub pkiadm.PublicKeyChange, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
pub, err := s.storage.GetPublicKey(pkiadm.ResourceName{
inPub.PublicKey.ID,
pkiadm.RTPublicKey,
})
if err != nil {
res.SetError(err, "Could not find public key '%s'", inPub.PublicKey.ID)
return nil
}
for _, field := range inPub.FieldList {
switch field {
case "private-key":
pub.PrivateKey = pkiadm.ResourceName{
inPub.PublicKey.ID,
pkiadm.RTPrivateKey,
}
default:
res.SetError(fmt.Errorf("unknown field"), "unknown field '%s'", field)
}
}
if err := s.storage.Update(pub.Name()); err != nil {
res.SetError(err, "Could not update new public key '%s'", inPub.PublicKey.ID)
return nil
}
return s.store(res)
}
func (s *Server) DeletePublicKey(inPub pkiadm.PublicKey, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
pub, err := s.storage.GetPublicKey(pkiadm.ResourceName{
inPub.ID,
pkiadm.RTPublicKey,
})
if err != nil {
res.SetError(err, "Could not find public key '%s'", inPub.ID)
return nil
}
if err := s.storage.Remove(pub); err != nil {
res.SetError(err, "Could not remove public key '%s'", inPub.ID)
return nil
}
return s.store(res)
}
func (s *Server) ShowPublicKey(inPub pkiadm.ResourceName, res *pkiadm.ResultPublicKey) error {
s.lock()
defer s.unlock()
pub, err := s.storage.GetPublicKey(inPub)
if err != nil {
res.Result.SetError(err, "Could not find public key '%s'", inPub.ID)
return nil
}
res.PublicKeys = []pkiadm.PublicKey{
pkiadm.PublicKey{
ID: pub.ID,
PrivateKey: pub.PrivateKey,
Type: pub.Type,
Checksum: pub.Checksum(),
},
}
return nil
}
func (s *Server) ListPublicKey(filter pkiadm.Filter, res *pkiadm.ResultPublicKey) error {
s.lock()
defer s.unlock()
for _, pub := range s.storage.PublicKeys {
res.PublicKeys = append(res.PublicKeys, pkiadm.PublicKey{
ID: pub.ID,
PrivateKey: pub.PrivateKey,
Type: pub.Type,
Checksum: pub.Checksum(),
})
}
return nil
}

View File

@ -1,16 +0,0 @@
// Code generated by "stringer -type PublicKeyType"; DO NOT EDIT
package main
import "fmt"
const _PublicKeyType_name = "PUTRSAPUTECDSAPUTED25519"
var _PublicKeyType_index = [...]uint8{0, 6, 14, 24}
func (i PublicKeyType) String() string {
if i >= PublicKeyType(len(_PublicKeyType_index)-1) {
return fmt.Sprintf("PublicKeyType(%d)", i)
}
return _PublicKeyType_name[_PublicKeyType_index[i]:_PublicKeyType_index[i+1]]
}

View File

@ -1,16 +0,0 @@
// Code generated by "stringer -type ResourceType"; DO NOT EDIT
package main
import "fmt"
const _ResourceType_name = "RTPrivateKeyRTPublicKeyRTCSRRTCertificateRTLocationRTSerialRTSubject"
var _ResourceType_index = [...]uint8{0, 12, 23, 28, 41, 51, 59, 68}
func (i ResourceType) String() string {
if i >= ResourceType(len(_ResourceType_index)-1) {
return fmt.Sprintf("ResourceType(%d)", i)
}
return _ResourceType_name[_ResourceType_index[i]:_ResourceType_index[i+1]]
}

62
public_key.go Normal file
View File

@ -0,0 +1,62 @@
package pkiadm
type (
PublicKey struct {
ID string
PrivateKey ResourceName
// The following attributes are filled in by the server and ignored
// otherwise.
Type PrivateKeyType // mark the type of the public key
Checksum []byte
}
PublicKeyChange struct {
FieldList []string
PublicKey PublicKey
}
ResultPublicKey struct {
Result Result
PublicKeys []PublicKey
}
)
func (c *Client) CreatePublicKey(pub PublicKey) error {
return c.exec("CreatePublicKey", pub)
}
func (c *Client) SetPublicKey(pub PublicKey, fieldList []string) error {
changeset := PublicKeyChange{fieldList, pub}
return c.exec("SetPublicKey", changeset)
}
func (c *Client) DeletePublicKey(pub PublicKey) error {
return c.exec("DeletePublicKey", pub)
}
func (c *Client) ListPublicKey() ([]PublicKey, error) {
result := &ResultPublicKey{}
if err := c.query("ListPublicKey", Filter{}, result); err != nil {
return []PublicKey{}, err
}
if result.Result.HasError {
return []PublicKey{}, result.Result.Error
}
return result.PublicKeys, nil
}
func (c *Client) ShowPublicKey(id string) (PublicKey, error) {
pk := ResourceName{ID: id, Type: RTPublicKey}
result := &ResultPublicKey{}
if err := c.query("ShowPublicKey", pk, result); err != nil {
return PublicKey{}, err
}
if result.Result.HasError {
return PublicKey{}, result.Result.Error
}
for _, publicKey := range result.PublicKeys {
return publicKey, nil
}
return PublicKey{}, nil
}