75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"time"
|
|
)
|
|
|
|
// No envelope here; server/UI define their own payload structs.
|
|
|
|
func parsePeerPublicKey(pemOrCert string) (*rsa.PublicKey, error) {
|
|
block, _ := pem.Decode([]byte(pemOrCert))
|
|
if block == nil {
|
|
return nil, errors.New("no PEM block found")
|
|
}
|
|
switch block.Type {
|
|
case "PUBLIC KEY":
|
|
k, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rsaPub, ok := k.(*rsa.PublicKey)
|
|
if !ok {
|
|
return nil, errors.New("expecting RSA PUBLIC KEY")
|
|
}
|
|
return rsaPub, nil
|
|
case "RSA PUBLIC KEY":
|
|
return x509.ParsePKCS1PublicKey(block.Bytes)
|
|
case "CERTIFICATE":
|
|
c, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rsaPub, ok := c.PublicKey.(*rsa.PublicKey)
|
|
if !ok {
|
|
return nil, errors.New("certificate does not contain RSA key")
|
|
}
|
|
return rsaPub, nil
|
|
default:
|
|
return nil, fmt.Errorf("unsupported PEM type: %s", block.Type)
|
|
}
|
|
}
|
|
|
|
func ParsePeerPublicKey(pemOrCert string) (*rsa.PublicKey, error) {
|
|
return parsePeerPublicKey(pemOrCert)
|
|
}
|
|
|
|
func generateSelfSignedCert(priv *rsa.PrivateKey, commonName string) ([]byte, error) {
|
|
if commonName == "" {
|
|
commonName = "Encryptor Local Identity"
|
|
}
|
|
tpl := &x509.Certificate{
|
|
SerialNumber: big.NewInt(time.Now().UnixNano()),
|
|
Subject: pkix.Name{CommonName: commonName},
|
|
NotBefore: time.Now().Add(-1 * time.Hour),
|
|
NotAfter: time.Now().AddDate(1, 0, 0),
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
BasicConstraintsValid: true,
|
|
}
|
|
der, err := x509.CreateCertificate(rand.Reader, tpl, tpl, &priv.PublicKey, priv)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
buf := &bytes.Buffer{}
|
|
_ = pem.Encode(buf, &pem.Block{Type: "CERTIFICATE", Bytes: der})
|
|
return buf.Bytes(), nil
|
|
}
|