Skip to content
Snippets Groups Projects
Commit 5c166a8b authored by kaiyou's avatar kaiyou
Browse files

Add a basic pki library

parent 061c214c
No related branches found
No related tags found
No related merge requests found
package pki
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/pem"
"errors"
"io/ioutil"
"os"
)
func getPem(path string) ([]byte, error) {
bytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
decoded, _ := pem.Decode(bytes)
if decoded == nil {
return nil, errors.New("Could not decode PEM file")
}
return decoded.Bytes, nil
}
func setPem(path string, blockType string, bytes []byte) error {
block := &pem.Block{
Type: blockType,
Bytes: bytes,
}
file, err := os.Create(path)
if err != nil {
return err
}
err = pem.Encode(file, block)
if err != nil {
return err
}
return file.Close()
}
func LoadKey(path string) (*ecdsa.PrivateKey, error) {
decoded, err := getPem(path)
if os.IsNotExist(err) {
return nil, nil
}
if err != nil {
return nil, err
}
return x509.ParseECPrivateKey(decoded)
}
func SaveKey(path string, key *ecdsa.PrivateKey) error {
keyBytes, err := x509.MarshalECPrivateKey(key)
if err != nil {
return err
}
return setPem(path, "ECDSA PRIVATE KEY", keyBytes)
}
func LoadCert(path string) (*x509.Certificate, error) {
decoded, err := getPem(path)
if os.IsNotExist(err) {
return nil, nil
}
if err != nil {
return nil, err
}
return x509.ParseCertificate(decoded)
}
func SaveCert(path string, cert *x509.Certificate) error {
return setPem(path, "CERTIFICATE", cert.Raw)
}
......@@ -6,9 +6,6 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"errors"
"io/ioutil"
"os"
"path/filepath"
)
......@@ -19,7 +16,7 @@ const CERT_EXT = ".pem"
type CA struct {
path string
signer *crypto.Signer
signer crypto.Signer
cert *x509.Certificate
}
......@@ -46,36 +43,63 @@ func GetCA(path string) (*CA, error) {
}, nil
}
func getPem(path string) ([]byte, error) {
bytes, err := ioutil.ReadFile(path)
func (c *CA) Sign(csrBytes []byte, template *x509.Certificate) ([]byte, error) {
csr, err := x509.ParseCertificateRequest(csrBytes)
if err != nil {
return nil, err
}
decoded, _ := pem.Decode(bytes)
if decoded == nil {
return nil, errors.New("Could not decode PEM file")
err = csr.CheckSignature()
if err != nil {
return nil, err
}
return decoded.Bytes, nil
// Fill the template fields in
template.Signature = csr.Signature
template.SignatureAlgorithm = csr.SignatureAlgorithm
template.PublicKey = csr.PublicKey
template.PublicKeyAlgorithm = csr.PublicKeyAlgorithm
// Actually sign the certificate
return x509.CreateCertificate(rand.Reader, template, c.cert, template.PublicKey, c.signer)
}
func getSigner(path string) (*crypto.Signer, error) {
decoded, err := getPem(path)
// Create the private key if necessary
if err == nil {
} else if os.IsExist(err) {
signer, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
func getSigner(path string) (crypto.Signer, error) {
key, err := LoadKey(path)
if err != nil {
return nil, err
}
// Create the key if necessary
if key == nil {
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
return nil, err
}
err = setPem(path, &pem.Block{
Type: "ECDSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(signer),
})
err = SaveKey(path, key)
if err != nil {
return err
return nil, err
}
} else {
}
return key, nil
}
func getCaCert(signer crypto.Signer, path string) (*x509.Certificate, error) {
cert, err := LoadCert(path)
if err != nil {
return nil, err
}
// Self-sign a certificate if required
if cert == nil {
template := NewCATemplate()
certBytes, err := x509.CreateCertificate(rand.Reader, template, template, signer.Public(), signer)
if err != nil {
return nil, err
}
cert, err = x509.ParseCertificate(certBytes)
if err != nil {
return nil, err
}
err = SaveCert(path, cert)
if err != nil {
return nil, err
}
}
return cert, nil
}
package pki
import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"time"
)
var maxSerial = new(big.Int).Lsh(big.NewInt(1), 128)
func newSerial() *big.Int {
serial, err := rand.Int(rand.Reader, maxSerial)
if err != nil {
panic(err)
}
return serial
}
func newTemplate() *x509.Certificate {
return &x509.Certificate{
SerialNumber: newSerial(),
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10),
BasicConstraintsValid: true,
}
}
func NewCATemplate() *x509.Certificate {
template := newTemplate()
template.Subject = pkix.Name{}
template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
template.IsCA = true
return template
}
func NewServerTemplate(names []string) *x509.Certificate {
template := newTemplate()
template.Subject = pkix.Name{
CommonName: names[0],
}
template.DNSNames = names
return template
}
func NewClientTemplate(cn string, org string) *x509.Certificate {
template := newTemplate()
template.Subject = pkix.Name{
CommonName: cn,
Organization: []string{org},
}
return template
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment