Initial commit of pkg functions
This commit is contained in:
parent
c325fa17e5
commit
6b6866077c
17 changed files with 1689 additions and 0 deletions
185
pkg/pemfile/pemfile.go
Normal file
185
pkg/pemfile/pemfile.go
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
package pemfile
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
||||
"src.lwithers.me.uk/go/writefile"
|
||||
)
|
||||
|
||||
const (
|
||||
TypePKCS1PrivateKey = "RSA PRIVATE KEY"
|
||||
TypePKCS8PrivateKey = "PRIVATE KEY"
|
||||
TypePKCS1PublicKey = "RSA PUBLIC KEY"
|
||||
TypePKIXPublicKey = "PUBLIC KEY"
|
||||
TypeX509Certificate = "CERTIFICATE"
|
||||
TypeX509CSR = "CERTIFICATE REQUEST"
|
||||
TypeX509CRL = "X509 CRL"
|
||||
)
|
||||
|
||||
func Write(filename, typ string, der []byte) error {
|
||||
finalFname, f, err := writefile.New(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer writefile.Abort(f)
|
||||
|
||||
out := bufio.NewWriter(f)
|
||||
pem.Encode(out, &pem.Block{
|
||||
Type: typ,
|
||||
Bytes: der,
|
||||
})
|
||||
if err = out.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
return writefile.Commit(finalFname, f)
|
||||
}
|
||||
|
||||
func ReadKey(filename string) (*rsa.PrivateKey, error) {
|
||||
raw, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
block, rest := pem.Decode(raw)
|
||||
raw = rest
|
||||
switch {
|
||||
case block == nil:
|
||||
return nil, &fs.PathError{
|
||||
Op: "decode",
|
||||
Path: filename,
|
||||
Err: errors.New("no private key PEM block found"),
|
||||
}
|
||||
|
||||
case block.Type == TypePKCS1PrivateKey:
|
||||
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse key",
|
||||
Path: filename,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return key, nil
|
||||
|
||||
case block.Type == TypePKCS8PrivateKey:
|
||||
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse key",
|
||||
Path: filename,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
rsakey, ok := key.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse key",
|
||||
Path: filename,
|
||||
Err: errors.New("not an RSA key"),
|
||||
}
|
||||
}
|
||||
return rsakey, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadCert(filename string) (*x509.Certificate, error) {
|
||||
raw, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
block, rest := pem.Decode(raw)
|
||||
raw = rest
|
||||
switch {
|
||||
case block == nil:
|
||||
return nil, &fs.PathError{
|
||||
Op: "decode",
|
||||
Path: filename,
|
||||
Err: errors.New("no certificate PEM block found"),
|
||||
}
|
||||
|
||||
case block.Type == TypeX509Certificate:
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse cert",
|
||||
Path: filename,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadCRL(filename string) (*x509.RevocationList, error) {
|
||||
raw, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
block, rest := pem.Decode(raw)
|
||||
raw = rest
|
||||
switch {
|
||||
case block == nil:
|
||||
return nil, &fs.PathError{
|
||||
Op: "decode",
|
||||
Path: filename,
|
||||
Err: errors.New("no CRL PEM block found"),
|
||||
}
|
||||
|
||||
case block.Type == TypeX509CRL:
|
||||
crl, err := x509.ParseRevocationList(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse cert",
|
||||
Path: filename,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return crl, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadCSR(filename string) (*x509.CertificateRequest, error) {
|
||||
raw, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
block, rest := pem.Decode(raw)
|
||||
raw = rest
|
||||
switch {
|
||||
case block == nil:
|
||||
return nil, &fs.PathError{
|
||||
Op: "decode",
|
||||
Path: filename,
|
||||
Err: errors.New("no CSR PEM block found"),
|
||||
}
|
||||
|
||||
case block.Type == TypeX509CSR:
|
||||
csr, err := x509.ParseCertificateRequest(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, &fs.PathError{
|
||||
Op: "parse CSR",
|
||||
Path: filename,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return csr, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue