aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md7
-rw-r--r--ecdsa.go69
-rw-r--r--pem_marshal.go15
-rw-r--r--rsa.go54
-rw-r--r--types.go31
5 files changed, 176 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8c9a336
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+pki
+===
+
+This is a small library to make building private keys, public keys, signatures
+and most of the certificate stuff a bit easier.
+
+For a cli you can take a look at [pkictl](https://git.zero-knowledge.org/gibheer/pkictl)
diff --git a/ecdsa.go b/ecdsa.go
new file mode 100644
index 0000000..170786b
--- /dev/null
+++ b/ecdsa.go
@@ -0,0 +1,69 @@
+package pkilib
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+)
+
+const (
+ PemLabelEcdsa = "EC PRIVATE KEY"
+)
+
+type (
+ // This type handles the function calls to the ecdsa private key by
+ // implementing the interface.
+ EcdsaPrivateKey struct {
+ private_key *ecdsa.PrivateKey
+ }
+
+ EcdsaPublicKey struct {
+ public_key *ecdsa.PublicKey
+ }
+)
+
+// generate a new ecdsa private key
+func NewPrivateKeyEcdsa(curve elliptic.Curve) (*EcdsaPrivateKey, error) {
+ key, err := ecdsa.GenerateKey(curve, rand.Reader)
+ if err != nil { return nil, err }
+ return &EcdsaPrivateKey{key}, nil
+}
+
+// load the private key from the raw data
+func LoadPrivateKeyEcdsa(raw []byte) (*EcdsaPrivateKey, error) {
+ key, err := x509.ParseECPrivateKey(raw)
+ if err != nil { return nil, err }
+ return &EcdsaPrivateKey{key}, nil
+}
+
+// derive a public key from the private key
+func (pr EcdsaPrivateKey) Public() PublicKey {
+ return &EcdsaPublicKey{pr.private_key.Public().(*ecdsa.PublicKey)}
+}
+
+// sign a message with the private key
+func (pr EcdsaPrivateKey) Sign(message []byte) ([]byte, error) {
+ return make([]byte, 0), errors.New("not implemented yet!")
+}
+
+// get the private key
+func (pr EcdsaPrivateKey) privateKey() crypto.PrivateKey {
+ return pr.private_key
+}
+
+// implement Pemmer interface
+func (pr EcdsaPrivateKey) MarshalPem() (marshalledPemBlock, error) {
+ asn1, err := x509.MarshalECPrivateKey(pr.private_key)
+ if err != nil { return nil, err }
+ pem_block := pem.Block{Type: PemLabelEcdsa, Bytes: asn1}
+ return pem.EncodeToMemory(&pem_block), nil
+}
+
+// verify a message using the ecdsa public key
+func (pu *EcdsaPublicKey) Verify(message []byte, signature []byte) (bool, error) {
+ return false, errors.New("not implemented yet!")
+}
diff --git a/pem_marshal.go b/pem_marshal.go
new file mode 100644
index 0000000..c9be63d
--- /dev/null
+++ b/pem_marshal.go
@@ -0,0 +1,15 @@
+package pkilib
+
+import (
+ "io"
+)
+
+type (
+ marshalledPemBlock []byte
+)
+
+// This function writes the marshalled pem block to a writer and returns the
+// number of written bytes and eventual errors.
+func (b marshalledPemBlock) WriteTo(stream io.Writer) (int, error) {
+ return stream.Write(b)
+}
diff --git a/rsa.go b/rsa.go
new file mode 100644
index 0000000..48135b2
--- /dev/null
+++ b/rsa.go
@@ -0,0 +1,54 @@
+package pkilib
+
+import (
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "errors"
+)
+
+type (
+ RsaPrivateKey struct {
+ private_key *rsa.PrivateKey
+ }
+
+ RsaPublicKey struct {
+ public_key rsa.PublicKey
+ }
+)
+
+// generate a new rsa private key
+func NewPrivateKeyRsa(size int) (*RsaPrivateKey, error) {
+ key, err := rsa.GenerateKey(rand.Reader, size)
+ if err != nil { return nil, err }
+ return &RsaPrivateKey{key}, nil
+}
+
+// load a rsa private key its ASN.1 presentation
+func LoadPrivateKeyRsa(raw []byte) (*RsaPrivateKey, error) {
+ key, err := x509.ParsePKCS1PrivateKey(raw)
+ if err != nil { return nil, err }
+ return &RsaPrivateKey{key}, nil
+}
+
+func (pr *RsaPrivateKey) Public() PublicKey {
+ return &RsaPublicKey{pr.private_key.Public().(rsa.PublicKey)}
+}
+
+func (pr RsaPrivateKey) Sign(message []byte) ([]byte, error) {
+ return make([]byte, 0), errors.New("not implemented yet!")
+}
+
+// get the private key
+func (pr RsaPrivateKey) privateKey() crypto.PrivateKey {
+ return pr.private_key
+}
+
+func (pr RsaPrivateKey) MarshalPem() (marshalledPemBlock, error) {
+ return nil, errors.New("not implemented yet!")
+}
+
+func (pu *RsaPublicKey) Verify(message []byte, signature []byte) (bool, error) {
+ return false, errors.New("not implemented yet!")
+}
diff --git a/types.go b/types.go
new file mode 100644
index 0000000..e9326ee
--- /dev/null
+++ b/types.go
@@ -0,0 +1,31 @@
+package pkilib
+
+import (
+ "crypto"
+)
+
+// this file holds all the interfaces used in the program until it can be split
+// properly
+
+type (
+ // interface for any private key
+ PrivateKey interface {
+ // derive a public key from the private key
+ Public() PublicKey
+ // sign a message with the private key
+ Sign(message []byte) ([]byte, error)
+
+ // return the private key structure
+ privateKey() crypto.PrivateKey
+ }
+
+ // interface for any public key
+ PublicKey interface {
+ // use the public key to verify a message against a signature
+ Verify(message []byte, signature []byte) (bool, error)
+ }
+
+ Pemmer interface {
+ MarshalPem() (marshalledPemBlock, error)
+ }
+)