package rsas
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"io"
"io/IoUtil"
"math/big"
rd "math/rand"
"net"
"os"
"path/filepath"
"time"
)
//var Certificate = struct {
// RootCA *x509.Certificate
// RootKey
//}{}
//func InitRootCA(crt,key string) (err error) {
// Certificate.RootCA,Certificate.RootKey,err = Parse(crt,key)
// return
//}
/* x := rsas.Certinformation{ Country: []string{"CH"},Organization: []string{"www.work-stacks.com"},OrganizationalUnit: []string{"Paas"},EmailAddress: []string{"czxichen@163.com"},Province: []string{"JS"},Locality: []string{"SZ"},CommonName: "master.work-stacks.com",DNSNames: []string{"master.work-stacks.com"},EncryptLen: 512,IsCA: true,DateLen: 5,} */
func init() {
rd.Seed(time.Now().UnixNano())
}
type Certinformation struct {
Country []string
Organization []string
OrganizationalUnit []string //使用者
EmailAddress []string
Province []string //省
Locality []string //市
CommonName string //域名
DNSNames []string
IPAddresses []net.IP
IsCA bool //是否是根证书
Names []pkix.AttributeTypeAndValue
CrtName,KeyName string
EncryptLen int //密钥长度
DateLen int //有效期,单位年
}
func SignerCRT(rootcrt *x509.Certificate,rootkey *rsa.PrivateKey,crt *x509.Certificate) ([]byte,error) {
if rootcrt == nil || rootkey == nil {
return nil,errors.New("Root crt is null")
}
buf,err := x509.CreateCertificate(rand.Reader,crt,rootcrt,crt.PublicKey,rootkey)
b := bytes.NewBuffer(nil)
err = Write(b,buf,"CERTIFICATE")
return b.Bytes(),err
}
func CheckSignature(rootcrt *x509.Certificate,crt []byte) error {
ca,err := ParseCrt(crt)
if err != nil {
return err
}
return ca.CheckSignatureFrom(rootcrt)
}
func CreatePemCRT(info Certinformation) (pemcrt []byte,pemkey []byte,err error) {
pemcrt,pemkey,err = CreateCRT(nil,nil,info)
if err != nil {
return
}
cFile := bytes.NewBuffer([]byte{})
err = Write(cFile,pemcrt,"CERTIFICATE")
if err != nil {
return
}
pemcrt = cFile.Bytes()
kFile := bytes.NewBuffer([]byte{})
err = Write(kFile,"PRIVATE KEY")
pemkey = kFile.Bytes()
return
}
func CreateCRT(RootCa *x509.Certificate,RootKey *rsa.PrivateKey,info Certinformation) (crt []byte,key []byte,err error) {
Crt := newCertificate(info)
if info.EncryptLen < 512 {
info.EncryptLen = 512
}
Key,err := rsa.GenerateKey(rand.Reader,info.EncryptLen)
if err != nil {
return
}
key = x509.MarshalPKCS1PrivateKey(Key)
if RootCa == nil || RootKey == nil {
crt,err = x509.CreateCertificate(rand.Reader,Crt,&Key.PublicKey,Key)
} else {
crt,RootCa,RootKey)
}
return
}
func WirteFile(path string,buf []byte,typ string) error {
os.MkdirAll(filepath.Dir(path), 0666)
File,err := os.Create(path)
defer File.Close()
if err != nil {
return err
}
return Write(File,typ)
}
func Write(w io.Writer,typ string) error {
b := &pem.Block{Bytes: buf,Type: typ}
return pem.Encode(w,b)
}
func Parse(crtPath,keyPath string) (rootcertificate *x509.Certificate,rootPrivateKey *rsa.PrivateKey,err error) {
buf,err := IoUtil.ReadFile(crtPath)
if err != nil {
return
}
rootcertificate,err = ParseCrt(buf)
if err != nil {
return
}
buf,err = IoUtil.ReadFile(keyPath)
if err != nil {
return
}
rootPrivateKey,err = ParseKey(buf)
return
}
func ParseCrt(buf []byte) (*x509.Certificate,error) {
p := &pem.Block{}
p,_ = pem.Decode(buf)
return x509.ParseCertificate(p.Bytes)
}
func ParseKey(buf []byte) (*rsa.PrivateKey,error) {
p,buf := pem.Decode(buf)
return x509.ParsePKCS1PrivateKey(p.Bytes)
}
func newCertificate(info Certinformation) *x509.Certificate {
if info.DateLen == 0 {
info.DateLen = 10
}
return &x509.Certificate{
SerialNumber: big.NewInt(rd.Int63()),Subject: pkix.Name{
Country: info.Country,Organization: info.Organization,OrganizationalUnit: info.OrganizationalUnit,Province: info.Province,CommonName: info.CommonName,Locality: info.Locality,ExtraNames: info.Names,},NotBefore: time.Now(),NotAfter: time.Now().AddDate(info.DateLen, 0, 0),BasicConstraintsValid: true,DNSNames: info.DNSNames,IPAddresses: info.IPAddresses,IsCA: info.IsCA,ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth,x509.ExtKeyUsageServerAuth},KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,EmailAddresses: info.EmailAddress,}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。