bitxhub/pkg/cert/cert.go

101 lines
2.5 KiB
Go

package cert
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"time"
"github.com/meshplus/bitxhub-kit/crypto"
ecdsa2 "github.com/meshplus/bitxhub-kit/crypto/asym/ecdsa"
)
func VerifySign(subCert *x509.Certificate, caCert *x509.Certificate) error {
if err := subCert.CheckSignatureFrom(caCert); err != nil {
return fmt.Errorf("check sign: %w", err)
}
if subCert.NotBefore.After(time.Now()) || subCert.NotAfter.Before(time.Now()) {
return fmt.Errorf("cert expired")
}
return nil
}
func ParsePrivateKey(data []byte, opt crypto.KeyType) (*ecdsa2.PrivateKey, error) {
if data == nil {
return nil, fmt.Errorf("empty data")
}
block, _ := pem.Decode(data)
if block == nil {
return nil, fmt.Errorf("empty block")
}
return ecdsa2.UnmarshalPrivateKey(block.Bytes, opt)
}
func ParseCert(data []byte) (*x509.Certificate, error) {
if data == nil {
return nil, fmt.Errorf("empty data")
}
block, _ := pem.Decode(data)
if block == nil {
return nil, fmt.Errorf("empty block")
}
return x509.ParseCertificate(block.Bytes)
}
func GenerateCert(privKey *ecdsa.PrivateKey, isCA bool, organization string) (*x509.Certificate, error) {
sn, err := rand.Int(rand.Reader, big.NewInt(1000000))
if err != nil {
return nil, err
}
notBefore := time.Now().Add(-5 * time.Minute).UTC()
template := &x509.Certificate{
SerialNumber: sn,
NotBefore: notBefore,
NotAfter: notBefore.Add(50 * 365 * 24 * time.Hour).UTC(),
BasicConstraintsValid: true,
IsCA: isCA,
KeyUsage: x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
Subject: pkix.Name{
Country: []string{"CN"},
Locality: []string{"HangZhou"},
Province: []string{"ZheJiang"},
OrganizationalUnit: []string{"BitXHub"},
Organization: []string{organization},
StreetAddress: []string{"street", "address"},
PostalCode: []string{"324000"},
CommonName: "bitxhub.cn",
},
}
template.SubjectKeyId = priKeyHash(privKey)
return template, nil
}
func priKeyHash(priKey *ecdsa.PrivateKey) []byte {
hash := sha256.New()
_, err := hash.Write(elliptic.Marshal(priKey.Curve, priKey.PublicKey.X, priKey.PublicKey.Y))
if err != nil {
fmt.Printf("Get private key hash: %s", err.Error())
return nil
}
return hash.Sum(nil)
}