Commit 09366cfa authored by pengjun's avatar pengjun Committed by vipwzw

#955 证书工具添加中间证书的生成

parent 5b40dfaa
...@@ -47,4 +47,5 @@ require ( ...@@ -47,4 +47,5 @@ require (
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
google.golang.org/grpc v1.29.1 google.golang.org/grpc v1.29.1
gopkg.in/yaml.v2 v2.2.4
) )
...@@ -25,9 +25,6 @@ var ( ...@@ -25,9 +25,6 @@ var (
alog = log.New("module", "authority") alog = log.New("module", "authority")
cpuNum = runtime.NumCPU() cpuNum = runtime.NumCPU()
// OrgName 默认证书组织名
OrgName = "Chain33"
// Author 全局证书校验器 // Author 全局证书校验器
Author = &Authority{} Author = &Authority{}
...@@ -369,12 +366,12 @@ func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error) ...@@ -369,12 +366,12 @@ func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error)
if err != nil { if err != nil {
return nil, fmt.Errorf("create crypto %s failed, error:%s", types.GetSignName("cert", loader.signType), err) return nil, fmt.Errorf("create crypto %s failed, error:%s", types.GetSignName("cert", loader.signType), err)
} }
privKeyByte, err := utils.PrivKeyByteFromRaw(keyBytes, loader.signType) //privKeyByte, err := utils.PrivKeyByteFromRaw(keyBytes, loader.signType)
if err != nil { //if err != nil {
return nil, err // return nil, err
} //}
priv, err := cr.PrivKeyFromBytes(privKeyByte) priv, err := cr.PrivKeyFromBytes(keyBytes)
if err != nil { if err != nil {
return nil, fmt.Errorf("get private key failed, error:%s", err) return nil, fmt.Errorf("get private key failed, error:%s", err)
} }
...@@ -383,8 +380,8 @@ func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error) ...@@ -383,8 +380,8 @@ func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error)
} }
// Get 根据用户名获取user结构 // Get 根据用户名获取user结构
func (loader *UserLoader) Get(userName string) (*User, error) { func (loader *UserLoader) Get(userName, orgName string) (*User, error) {
keyvalue := fmt.Sprintf("%s@%s-cert.pem", userName, OrgName) keyvalue := fmt.Sprintf("%s@%s-cert.pem", userName, orgName)
user, ok := loader.userMap[keyvalue] user, ok := loader.userMap[keyvalue]
if !ok { if !ok {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
......
...@@ -54,7 +54,8 @@ var ( ...@@ -54,7 +54,8 @@ var (
} }
) )
var USERNAME = "User" var USERNAME = "user1"
var ORGNAME = "org1"
var SIGNTYPE = ct.AuthSM2 var SIGNTYPE = ct.AuthSM2
func signtx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) { func signtx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) {
...@@ -98,7 +99,7 @@ func initEnv() (*types.Chain33Config, error) { ...@@ -98,7 +99,7 @@ func initEnv() (*types.Chain33Config, error) {
return nil, err return nil, err
} }
user, err := userLoader.Get(USERNAME) user, err := userLoader.Get(USERNAME, ORGNAME)
if err != nil { if err != nil {
fmt.Printf("Get user failed") fmt.Printf("Get user failed")
return nil, err return nil, err
...@@ -124,10 +125,7 @@ func TestChckSign(t *testing.T) { ...@@ -124,10 +125,7 @@ func TestChckSign(t *testing.T) {
} }
cfg.SetMinFee(0) cfg.SetMinFee(0)
if !tx1.CheckSign() { assert.Equal(t, true, tx1.CheckSign())
t.Error("check signature failed")
return
}
} }
/** /**
......
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIB7DCCAZGgAwIBAgIQETH0EMzvdWOEEg3FoAe/iDAKBggqgRzPVQGDdTBHMQsw MIIB8jCCAZigAwIBAgIRANAVs0iZuoUGkmEpb9KbDHgwCgYIKoEcz1UBg3UwSjEO
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy MAwGA1UEBhMFQ2hpbmExETAPBgNVBAgTCFpoZWppYW5nMREwDwYDVQQHEwhIYW5n
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky emhvdTESMBAGA1UEAxMJQ2hhaW4zM0NBMB4XDTIxMDIwNTA5NTAyOFoXDTIxMDUx
NTIwWjBHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE NjA5NTAyOFowSjEOMAwGA1UEBhMFQ2hpbmExETAPBgNVBAgTCFpoZWppYW5nMREw
BxMNU2FuIEZyYW5jaXNjbzELMAkGA1UEAxMCY2EwWTATBgcqhkjOPQIBBggqgRzP DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEAxMJQ2hhaW4zM0NBMFkwEwYHKoZIzj0C
VQGCLQNCAAQlKmH6RVHN/nBE4qR+uF7lHmlc62jQA4kpoAwtJFRiFbczZx/KNDaD AQYIKoEcz1UBgi0DQgAEu+f1TgnsUOKPmI6f9V2iTTMm0SoJuPXV/oG88jwVUh9e
9+USLAo9ecxcdOKR4lIcuT7jvKX6tXQ7o18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYD viiugGXJ+WSL58KceRmZT5zTvzJ5OzjsfxJFb9G4PqNfMF0wDgYDVR0PAQH/BAQD
VR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCC8fKlLiayf AgGmMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQg
+80blLEiRIzTyY7uYDUpP5K2RtOmfY0NKjAKBggqgRzPVQGDdQNJADBGAiEA8vh+ ocyVo2jZzw/MNHGLXlWoWTweHuDfGQ9YduMQvhC7qlUwCgYIKoEcz1UBg3UDSAAw
3joELxPxq0n1h07XFGeEnmpxutVoIocuky2HkF4CIQDnWIavlpJOq3tU76cmn3ur RQIhAIAOBIKqOK5R0lt/h9G/SlgzGSazEOStJ6Q1hGuhEctAAiBGVtGHlOwV0L8g
KQeyi9GM7Uoi25S1QIxu9A== 6pMvlk46rpq3BNHFQiW1MeALRb+qqg==
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB8TCCAZigAwIBAgIRANBfNdKA1MB2NGdS6W6HLZAwCgYIKoEcz1UBg3UwSjEO
MAwGA1UEBhMFQ2hpbmExETAPBgNVBAgTCFpoZWppYW5nMREwDwYDVQQHEwhIYW5n
emhvdTESMBAGA1UEAxMJQ2hhaW4zM0NBMB4XDTIxMDIwNTA5NTAyOFoXDTIxMDUx
NjA5NTAyOFowSjEOMAwGA1UEBhMFQ2hpbmExETAPBgNVBAgTCFpoZWppYW5nMREw
DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEAxMJQ2hhaW4zM0NBMFkwEwYHKoZIzj0C
AQYIKoEcz1UBgi0DQgAEE7meX04w0TkLMxVhKDIHNosXUp0Ko1XOXd8rm+SaMSjQ
dFyAO98YZcR+pVjzT2hs/8JHm8UtEt5MSsNA80pG7KNfMF0wDgYDVR0PAQH/BAQD
AgGmMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQg
k+DGCc4DXJrEhGEK0K2DhBRiNsJX1VNqCQdp1dplx5QwCgYIKoEcz1UBg3UDRwAw
RAIgRTG6r1EPLmvaX8VKKDDIIUthYKWY4gao4e2QBYvTFGcCICcxdwnDdDTwo8N+
KKWn1mulB/+1uVFa8ur8K7C2juJA
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg4Ork9oT6d6CRxg0f
EbHlr5eQPUcHWniEgRhDCi2dA/GgCgYIKoEcz1UBgi2hRANCAAQqXuEWh+sW/YtP
FlHmxiFhYi0o3Tb8He9NAaJ6uKe+OF5/eXa+VmRrKKGeE+dG8LrMiJ5+AlIj+ryd
blX5UKZ8
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIB4zCCAYmgAwIBAgIQVs0txvOG+iVu/oISaV2KyzAKBggqgRzPVQGDdTBHMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky
NTIwWjBRMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEAwwMVXNlckBDaGFpbjMzMFkwEwYHKoZI
zj0CAQYIKoEcz1UBgi0DQgAEKl7hFofrFv2LTxZR5sYhYWItKN02/B3vTQGierin
vjhef3l2vlZkayihnhPnRvC6zIiefgJSI/q8nW5V+VCmfKNNMEswDgYDVR0PAQH/
BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgvHypS4msn/vNG5SxIkSM
08mO7mA1KT+StkbTpn2NDSowCgYIKoEcz1UBg3UDSAAwRQIhAND6HO/EN/dTeokX
mIvczQBcxPHTAq3+QIa2NHIC8bYvAiAZ5N4C4rwRJCqTw8J6As69MFO10XixWHxH
qrTJ9LnI3g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB2zCCAYKgAwIBAgIQBfpCKYMGwcsdTSfiRMUEvjAKBggqgRzPVQGDdTBKMQ4w
DAYDVQQGEwVDaGluYTERMA8GA1UECBMIWmhlamlhbmcxETAPBgNVBAcTCEhhbmd6
aG91MRIwEAYDVQQDEwlDaGFpbjMzQ0EwHhcNMjEwMjA1MDk1MDI4WhcNMjEwNTE2
MDk1MDI4WjBHMQ4wDAYDVQQGEwVDaGluYTERMA8GA1UECBMIWmhlamlhbmcxETAP
BgNVBAcTCEhhbmd6aG91MQ8wDQYDVQQDEwZvcmcxQ0EwWTATBgcqhkjOPQIBBggq
gRzPVQGCLQNCAAQ89ud/ijDdF+TTxMGOLhhFy7qpEF/ALFaXmrDB0kZ4xJSzcMVz
BHLJK+TQPfUYkIvDJGIWCQcozKHT+UbzvAtjo00wSzAOBgNVHQ8BAf8EBAMCB4Aw
DAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCCT4MYJzgNcmsSEYQrQrYOEFGI2wlfV
U2oJB2nV2mXHlDAKBggqgRzPVQGDdQNHADBEAiBKKc5DPV2F73fwe8oZqiIOc9U8
xX+jMZPCOqMzFxZ/UwIgRARNhW60dHNse7zYvC49gIMsDfVxbHYfNxiRzsl6168=
-----END CERTIFICATE-----
## 用户名,可配置多用户
name = ["User"]
## 签名类型,支持"auth_ecdsa", "auth_sm2"
signType = "auth_sm2"
\ No newline at end of file
SignType: auth_sm2
Root:
Name: ca
CA:
CommonName: Chain33CA
Country: China
Province: Zhejiang
Locality: Hangzhou
Expire: 100
User:
- Name: org1
- Name: org2
Organizations:
- Name: org1
CA:
CommonName: org1CA
Country: China
Province: Zhejiang
Locality: Hangzhou
Expire: 100
User:
- Name: user1
- Name: user2
- Name: org2
CA:
CommonName: org2CA
Country: China
Province: Zhejiang
Locality: Hangzhou
Expire: 100
User:
- Name: user1
- Name: user2
\ No newline at end of file
...@@ -6,49 +6,43 @@ package main ...@@ -6,49 +6,43 @@ package main
import ( import (
"fmt" "fmt"
log "github.com/33cn/chain33/common/log/log15"
"gopkg.in/yaml.v2"
"os" "os"
"path/filepath" "path/filepath"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
_ "github.com/33cn/plugin/plugin/crypto/init" _ "github.com/33cn/plugin/plugin/crypto/init"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator" "github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator"
ca "github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator/impl"
"github.com/BurntSushi/toml"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( const (
// CANAME 默认CA名称
CANAME = "ca"
// CONFIGFILENAME 配置文件名 // CONFIGFILENAME 配置文件名
CONFIGFILENAME = "chain33.cryptogen.toml" CONFIGFILENAME = "chain33.cryptogen.yaml"
// OUTPUTDIR 证书文件输出路径 // OUTPUTDIR 证书文件输出路径
OUTPUTDIR = "./authdir/crypto" OUTPUTDIR = "./authdir/crypto"
// ORGNAME 默认组织名
ORGNAME = "Chain33"
) )
// Config 证书生成工具配置
type Config struct {
Name []string
SignType string
}
var ( var (
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: "cryptogen [-f configfile] [-o output directory]", Use: "cryptogen [-f configfile] [-o output directory]",
Short: "chain33 crypto tool for generating key and certificate", Short: "chain33 crypto tool for generating key and certificate",
Run: generate, Run: generate,
} }
cfg Config cfg *generator.GenConfig
logger = log.New("module", "main")
) )
func initCfg(path string) *Config { func initCfg(path string) (*generator.GenConfig, error) {
if _, err := toml.DecodeFile(path, &cfg); err != nil { conf := &generator.GenConfig{}
fmt.Println(err) f, err := os.Open(path)
os.Exit(0) if err != nil {
return nil, err
} }
return &cfg
yaml.NewDecoder(f).Decode(conf)
return conf, nil
} }
func main() { func main() {
...@@ -65,19 +59,22 @@ func generate(cmd *cobra.Command, args []string) { ...@@ -65,19 +59,22 @@ func generate(cmd *cobra.Command, args []string) {
configfile, _ := cmd.Flags().GetString("configfile") configfile, _ := cmd.Flags().GetString("configfile")
outputdir, _ := cmd.Flags().GetString("outputdir") outputdir, _ := cmd.Flags().GetString("outputdir")
initCfg(configfile) var err error
fmt.Println(cfg.Name) cfg, err = initCfg(configfile)
if err != nil {
panic(err)
}
generateCert(outputdir)
generateUsers(outputdir, ORGNAME)
} }
func generateUsers(baseDir string, orgName string) { func generateCert(baseDir string) {
fmt.Printf("generateUsers\n") logger.Info("generate certs", "dir", baseDir)
fmt.Println(baseDir)
err := os.RemoveAll(baseDir) err := os.RemoveAll(baseDir)
if err != nil { if err != nil {
fmt.Printf("Clean directory %s error", baseDir) logger.Error("clean directory", "error", err.Error())
os.Exit(1) os.Exit(1)
} }
...@@ -85,26 +82,37 @@ func generateUsers(baseDir string, orgName string) { ...@@ -85,26 +82,37 @@ func generateUsers(baseDir string, orgName string) {
signType := types.GetSignType("cert", cfg.SignType) signType := types.GetSignType("cert", cfg.SignType)
if signType == types.Invalid { if signType == types.Invalid {
fmt.Printf("Invalid sign type:%s", cfg.SignType) logger.Error("invalid sign type", "type", cfg.SignType)
return return
} }
signCA, err := ca.NewCA(caDir, CANAME, signType) signCA, err := generator.NewCA(caDir, &cfg.Root, signType)
if err != nil { if err != nil {
fmt.Printf("Error generating signCA:%s", err.Error()) logger.Error("generating signCA", "error", err.Error())
os.Exit(1) os.Exit(1)
} }
generateNodes(baseDir, signCA, orgName) for _, org := range cfg.Root.User {
generateOrgs(baseDir, signCA, cfg.GetOrgCertConfig(org.Name))
}
} }
func generateNodes(baseDir string, signCA generator.CAGenerator, orgName string) { func generateOrgs(baseDir string, signCA generator.CAGenerator, orgCfg *generator.CertConfig) {
for _, name := range cfg.Name { orgDir := filepath.Join(baseDir, orgCfg.Name)
userDir := filepath.Join(baseDir, name) fileName := fmt.Sprintf("%s@%s", orgCfg.Name, cfg.Root.Name)
fileName := fmt.Sprintf("%s@%s", name, orgName) orgSignCA, err := signCA.GenerateLocalOrg(orgDir, fileName, orgCfg)
err := signCA.GenerateLocalUser(userDir, fileName) if err != nil {
logger.Error("generating local org", "org", orgCfg.Name, "error", err.Error())
os.Exit(1)
}
for _, user := range orgCfg.User {
userDir := filepath.Join(orgDir, user.Name)
fileName = fmt.Sprintf("%s@%s", user.Name, orgCfg.Name)
err := orgSignCA.GenerateLocalUser(userDir, fileName)
if err != nil { if err != nil {
fmt.Printf("Error generating local user") logger.Error("generating local user", "user", user.Name, "error", err.Error())
os.Exit(1) os.Exit(1)
} }
} }
......
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
auth "github.com/33cn/plugin/plugin/dapp/cert/authority/utils" auth "github.com/33cn/plugin/plugin/dapp/cert/authority/utils"
) )
var logger = log.New("tools", "cryptogen") var logger = log.New("module", "tools")
// NewFileBasedKeyStore 创建key存储器 // NewFileBasedKeyStore 创建key存储器
func NewFileBasedKeyStore(pwd []byte, path string, readOnly bool) (KeyStore, error) { func NewFileBasedKeyStore(pwd []byte, path string, readOnly bool) (KeyStore, error) {
...@@ -65,6 +65,7 @@ func (ks *fileBasedKeyStore) Init(pwd []byte, path string, readOnly bool) error ...@@ -65,6 +65,7 @@ func (ks *fileBasedKeyStore) Init(pwd []byte, path string, readOnly bool) error
} }
ks.readOnly = readOnly ks.readOnly = readOnly
logger.Info("generate keystore file", "path", path)
return nil return nil
} }
...@@ -85,7 +86,7 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) { ...@@ -85,7 +86,7 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) {
case *ecdsaPrivateKey: case *ecdsaPrivateKey:
kk := k.(*ecdsaPrivateKey) kk := k.(*ecdsaPrivateKey)
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey) err = ks.storePrivateKeyByte(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil { if err != nil {
return fmt.Errorf("Failed storing ECDSA private key [%s]", err) return fmt.Errorf("Failed storing ECDSA private key [%s]", err)
} }
...@@ -100,7 +101,7 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) { ...@@ -100,7 +101,7 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) {
case *SM2PrivateKey: case *SM2PrivateKey:
kk := k.(*SM2PrivateKey) kk := k.(*SM2PrivateKey)
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.PrivKey) err = ks.storePrivateKeyByte(hex.EncodeToString(k.SKI()), kk.PrivKey)
if err != nil { if err != nil {
return fmt.Errorf("Failed storing SM2 private key [%s]", err) return fmt.Errorf("Failed storing SM2 private key [%s]", err)
} }
...@@ -119,16 +120,32 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) { ...@@ -119,16 +120,32 @@ func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) {
return return
} }
func (ks *fileBasedKeyStore) storePrivateKeyByte(alias string, privateKey interface{}) error {
rawKey, err := utils.PrivateKeyToByte(privateKey)
if err != nil {
logger.Error("Failed converting private key to PEM","name", alias, "error", err)
return err
}
err = ioutil.WriteFile(ks.getPathForAlias(alias, "sk"), rawKey, 0700)
if err != nil {
logger.Error("Failed storing private key", "name", alias, "error", err)
return err
}
return nil
}
func (ks *fileBasedKeyStore) storePrivateKey(alias string, privateKey interface{}) error { func (ks *fileBasedKeyStore) storePrivateKey(alias string, privateKey interface{}) error {
rawKey, err := utils.PrivateKeyToPEM(privateKey, ks.pwd) rawKey, err := utils.PrivateKeyToPEM(privateKey, ks.pwd)
if err != nil { if err != nil {
logger.Error("Failed converting private key to PEM [%s]: [%s]", alias, err) logger.Error("Failed converting private key to PEM", "name", alias, "error", err)
return err return err
} }
err = ioutil.WriteFile(ks.getPathForAlias(alias, "sk"), rawKey, 0700) err = ioutil.WriteFile(ks.getPathForAlias(alias, "sk"), rawKey, 0700)
if err != nil { if err != nil {
logger.Error("Failed storing private key [%s]: [%s]", alias, err) logger.Error("Failed storing private key", "name", alias, "error", err)
return err return err
} }
...@@ -138,13 +155,13 @@ func (ks *fileBasedKeyStore) storePrivateKey(alias string, privateKey interface{ ...@@ -138,13 +155,13 @@ func (ks *fileBasedKeyStore) storePrivateKey(alias string, privateKey interface{
func (ks *fileBasedKeyStore) storePublicKey(alias string, publicKey interface{}) error { func (ks *fileBasedKeyStore) storePublicKey(alias string, publicKey interface{}) error {
rawKey, err := utils.PublicKeyToPEM(publicKey, ks.pwd) rawKey, err := utils.PublicKeyToPEM(publicKey, ks.pwd)
if err != nil { if err != nil {
logger.Error("Failed converting public key to PEM [%s]: [%s]", alias, err) logger.Error("Failed converting public key to PEM", "name", alias, "error", err)
return err return err
} }
err = ioutil.WriteFile(ks.getPathForAlias(alias, "pk"), rawKey, 0700) err = ioutil.WriteFile(ks.getPathForAlias(alias, "pk"), rawKey, 0700)
if err != nil { if err != nil {
logger.Error("Failed storing private key [%s]: [%s]", alias, err) logger.Error("Failed storing public key", "name", alias, "error", err)
return err return err
} }
...@@ -157,7 +174,7 @@ func (ks *fileBasedKeyStore) createKeyStoreIfNotExists() error { ...@@ -157,7 +174,7 @@ func (ks *fileBasedKeyStore) createKeyStoreIfNotExists() error {
if missing { if missing {
err := ks.createKeyStore() err := ks.createKeyStore()
if err != nil { if err != nil {
logger.Error("Failed creating KeyStore At [%s]: [%s]", ksPath, err.Error()) logger.Error("Failed creating KeyStore At", "path", ksPath, "error", err.Error())
return err return err
} }
} }
......
...@@ -41,10 +41,17 @@ type sm2KeyGenerator struct { ...@@ -41,10 +41,17 @@ type sm2KeyGenerator struct {
} }
func (kg *sm2KeyGenerator) KeyGen(opts int) (k Key, err error) { func (kg *sm2KeyGenerator) KeyGen(opts int) (k Key, err error) {
privKey, err := sm2.GenerateKey() ln := big.NewInt(0).Rsh(sm2.P256Sm2().Params().N, 1)
if err != nil { for {
return nil, fmt.Errorf("Failed generating SM2 key for: [%s]", err) privKey, err := sm2.GenerateKey()
if err != nil {
return nil, fmt.Errorf("Failed generating SM2 key for: [%s]", err)
}
if ln.Cmp(privKey.D) == 1 {
//fmt.Println("priv:"+common.ToHex(privKey.D.Bytes()))
return &SM2PrivateKey{privKey}, nil
}
} }
return &SM2PrivateKey{privKey}, nil
} }
...@@ -12,7 +12,9 @@ import ( ...@@ -12,7 +12,9 @@ import (
"encoding/asn1" "encoding/asn1"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
pkecdsa "github.com/33cn/plugin/plugin/crypto/ecdsa"
pkesm2 "github.com/33cn/plugin/plugin/crypto/sm2"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tjfoc/gmsm/sm2" "github.com/tjfoc/gmsm/sm2"
) )
...@@ -44,6 +46,21 @@ func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { ...@@ -44,6 +46,21 @@ func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
return nil, false return nil, false
} }
func PrivateKeyToByte(privateKey interface{}) ([]byte, error) {
if privateKey == nil {
return nil, errors.New("Invalid key. It must be different from nil")
}
switch k := privateKey.(type) {
case *ecdsa.PrivateKey:
return []byte(common.Bytes2Hex(pkecdsa.SerializePrivateKey(k))), nil
case *sm2.PrivateKey:
return []byte(common.Bytes2Hex(pkesm2.SerializePrivateKey(k))), nil
default:
return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey")
}
}
// PrivateKeyToPEM 私钥转pem // PrivateKeyToPEM 私钥转pem
func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) { func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
if len(pwd) != 0 { if len(pwd) != 0 {
......
package generator
type UserConfig struct {
Name string `yaml:"Name"`
}
type CAConfig struct {
CommonName string `yaml:"CommonName"`
Country string `yaml:"Country"`
Province string `yaml:"Province"`
Locality string `yaml:"Locality"`
Expire int `yaml:"Expire"`
}
type CertConfig struct {
Name string `yaml:"Name"`
CA CAConfig `yaml:"CA"`
User []UserConfig `yaml:"User"`
}
type GenConfig struct {
SignType string `yaml:"SignType"`
Root CertConfig `yaml:"Root"`
Organizations []CertConfig `yaml:"Organizations"`
}
func (cfg *GenConfig) GetOrgCertConfig(orgName string) *CertConfig {
for _, certCfg := range cfg.Organizations {
if certCfg.Name == orgName {
return &certCfg
}
}
return nil
}
...@@ -8,7 +8,9 @@ import "crypto/x509" ...@@ -8,7 +8,9 @@ import "crypto/x509"
// CAGenerator CA生成器接口 // CAGenerator CA生成器接口
type CAGenerator interface { type CAGenerator interface {
SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error) SignCertificate(baseDir, fileName string, sans []string, pub interface{}, isCA bool) (*x509.Certificate, error)
GenerateLocalUser(baseDir, name string) error GenerateLocalOrg(baseDir, fileName string, orgCfg *CertConfig) (CAGenerator, error)
GenerateLocalUser(baseDir, fileName string) error
} }
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package generator
import (
"crypto"
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"time"
"path/filepath"
"fmt"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/factory/csp"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator/utils"
ut "github.com/33cn/plugin/plugin/dapp/cert/authority/utils"
ty "github.com/33cn/plugin/plugin/dapp/cert/types"
"github.com/tjfoc/gmsm/sm2"
)
// EcdsaCA ecdsa CA结构
type EcdsaCA struct {
Name string
Signer crypto.Signer
SignCert *x509.Certificate
CertConfig *CertConfig
}
// SM2CA SM2 CA结构
type SM2CA struct {
Name string
Signer crypto.Signer
SignCert *sm2.Certificate
Sm2Key csp.Key
CertConfig *CertConfig
}
// NewCA 根据类型生成CA生成器
func NewCA(baseDir string, cacfg *CertConfig, signType int) (CAGenerator, error) {
if signType == ty.AuthECDSA {
return newEcdsaCA(baseDir, cacfg)
} else if signType == ty.AuthSM2 {
return newSM2CA(baseDir, cacfg)
} else {
return nil, fmt.Errorf("Invalid sign type")
}
}
func newEcdsaCA(baseDir string, certConfig *CertConfig) (*EcdsaCA, error) {
err := os.MkdirAll(baseDir, 0750)
if err != nil {
return nil, err
}
var ca *EcdsaCA
priv, signer, err := utils.GeneratePrivateKey(baseDir, csp.ECDSAP256KeyGen)
if err != nil {
return nil, err
}
ecPubKey, err := utils.GetECPublicKey(priv)
if err != nil {
return nil, err
}
template := x509Template(certConfig.CA.Expire)
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
subject := pkix.Name{
Country: []string{certConfig.CA.Country},
Locality: []string{certConfig.CA.Locality},
Province: []string{certConfig.CA.Province},
}
subject.CommonName = certConfig.CA.CommonName
template.Subject = subject
template.SubjectKeyId = priv.SKI()
template.PublicKey = ecPubKey
x509Cert, err := genCertificateECDSA(baseDir, certConfig.Name, &template, &template, signer)
if err != nil {
return nil, err
}
ca = &EcdsaCA{
Name: certConfig.Name,
Signer: signer,
SignCert: x509Cert,
CertConfig: certConfig,
}
return ca, nil
}
// SignCertificate 证书签名
func (ca *EcdsaCA) SignCertificate(baseDir, fileName string, sans []string, pub interface{}, isCA bool) (*x509.Certificate, error) {
template := x509Template(ca.CertConfig.CA.Expire)
if isCA {
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
template.SubjectKeyId = ut.SKI(pub.(*ecdsa.PublicKey).Curve, pub.(*ecdsa.PublicKey).X, pub.(*ecdsa.PublicKey).Y)
} else {
template.KeyUsage = x509.KeyUsageDigitalSignature
template.ExtKeyUsage = []x509.ExtKeyUsage{}
}
subject := pkix.Name{
Country: []string{ca.CertConfig.CA.Country},
Locality: []string{ca.CertConfig.CA.Locality},
Province: []string{ca.CertConfig.CA.Province},
}
subject.CommonName = ca.CertConfig.CA.CommonName
template.Subject = subject
template.DNSNames = sans
template.PublicKey = pub
cert, err := genCertificateECDSA(baseDir, fileName, &template, ca.SignCert, ca.Signer)
if err != nil {
return nil, err
}
return cert, nil
}
// GenerateLocalOrg 生成组织证书
func (ca *EcdsaCA) GenerateLocalOrg(baseDir, fileName string, orgCfg *CertConfig) (CAGenerator, error) {
err := createFolderStructure(baseDir, true)
if err != nil {
return nil, err
}
keystore := filepath.Join(baseDir, "keystore")
priv, signer, err := utils.GeneratePrivateKey(keystore, csp.ECDSAP256KeyGen)
if err != nil {
return nil, err
}
ecPubKey, err := utils.GetECPublicKey(priv)
if err != nil {
return nil, err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), fileName, []string{}, ecPubKey, true)
if err != nil || cert == nil {
return nil, err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(fileName)), ca.SignCert.Raw)
if err != nil {
return nil, err
}
err = x509Export(filepath.Join(baseDir, "intermediatecerts", x509Filename(orgCfg.Name)), cert.Raw)
if err != nil {
return nil, err
}
orgCA := &EcdsaCA{
Name: ca.Name,
Signer: signer,
SignCert: cert,
CertConfig: orgCfg,
}
return orgCA, nil
}
// GenerateLocalUser 生成本地用户
func (ca *EcdsaCA) GenerateLocalUser(baseDir, fileName string) error {
err := createFolderStructure(baseDir, false)
if err != nil {
return err
}
keystore := filepath.Join(baseDir, "keystore")
priv, _, err := utils.GeneratePrivateKey(keystore, csp.ECDSAP256KeyGen)
if err != nil {
return err
}
ecPubKey, err := utils.GetECPublicKey(priv)
if err != nil {
return err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), fileName, []string{}, ecPubKey, false)
if err != nil || cert == nil {
return err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(ca.Name)), ca.SignCert.Raw)
return err
}
func x509Template(expire int) x509.Certificate {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
expiry := time.Duration(expire) * 24 * time.Hour
notBefore := time.Now().Add(-5 * time.Minute).UTC()
x509 := x509.Certificate{
SerialNumber: serialNumber,
NotBefore: notBefore,
NotAfter: notBefore.Add(expiry).UTC(),
BasicConstraintsValid: true,
}
return x509
}
func genCertificateECDSA(baseDir, fileName string, template, parent *x509.Certificate, priv interface{}) (*x509.Certificate, error) {
certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, template.PublicKey, priv)
if err != nil {
return nil, err
}
fullName := filepath.Join(baseDir, fileName+"-cert.pem")
certFile, err := os.Create(fullName)
if err != nil {
return nil, err
}
defer certFile.Close()
err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
if err != nil {
return nil, err
}
x509Cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, err
}
return x509Cert, nil
}
func newSM2CA(baseDir string, certConfig *CertConfig) (*SM2CA, error) {
var ca *SM2CA
priv, signer, err := utils.GeneratePrivateKey(baseDir, csp.SM2P256KygGen)
if err != nil {
return nil, err
}
smPubKey, err := utils.GetSM2PublicKey(priv)
if err != nil {
return nil, err
}
template := x509Template(certConfig.CA.Expire)
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
subject := pkix.Name{
Country: []string{certConfig.CA.Country},
Locality: []string{certConfig.CA.Locality},
Province: []string{certConfig.CA.Province},
}
subject.CommonName = certConfig.CA.CommonName
template.Subject = subject
template.SubjectKeyId = priv.SKI()
sm2cert := utils.ParseX509CertificateToSm2(&template)
sm2cert.PublicKey = smPubKey
x509Cert, err := genCertificateGMSM2(baseDir, certConfig.Name, sm2cert, sm2cert, signer)
if err != nil {
return nil, err
}
ca = &SM2CA{
Name: certConfig.Name,
Signer: signer,
SignCert: x509Cert,
Sm2Key: priv,
CertConfig: certConfig,
}
return ca, nil
}
// SignCertificate 证书签名
func (ca *SM2CA) SignCertificate(baseDir, fileName string, sans []string, pub interface{}, isCA bool) (*x509.Certificate, error) {
template := x509Template(ca.CertConfig.CA.Expire)
if isCA {
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
template.SubjectKeyId = ut.SKI(pub.(*sm2.PublicKey).Curve, pub.(*sm2.PublicKey).X, pub.(*sm2.PublicKey).Y)
} else {
template.KeyUsage = x509.KeyUsageDigitalSignature
template.ExtKeyUsage = []x509.ExtKeyUsage{}
}
subject := pkix.Name{
Country: []string{ca.CertConfig.CA.Country},
Locality: []string{ca.CertConfig.CA.Locality},
Province: []string{ca.CertConfig.CA.Province},
}
subject.CommonName = ca.CertConfig.CA.CommonName
template.Subject = subject
template.DNSNames = sans
template.PublicKey = pub
sm2Tpl := utils.ParseX509CertificateToSm2(&template)
cert, err := genCertificateGMSM2(baseDir, fileName, sm2Tpl, ca.SignCert, ca.Signer)
if err != nil {
return nil, err
}
return utils.ParseSm2CertificateToX509(cert), nil
}
// GenerateLocalOrg 生成组织证书
func (ca *SM2CA) GenerateLocalOrg(baseDir, fileName string, orgCfg *CertConfig) (CAGenerator, error) {
err := createFolderStructure(baseDir, true)
if err != nil {
return nil, err
}
keystore := filepath.Join(baseDir, "keystore")
priv, signer, err := utils.GeneratePrivateKey(keystore, csp.SM2P256KygGen)
if err != nil {
return nil, err
}
sm2PubKey, err := utils.GetSM2PublicKey(priv)
if err != nil {
return nil, err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), fileName, []string{}, sm2PubKey, true)
if err != nil || cert == nil {
return nil, err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(ca.Name)), ca.SignCert.Raw)
if err != nil {
return nil, err
}
err = x509Export(filepath.Join(baseDir, "intermediatecerts", x509Filename(orgCfg.Name)), cert.Raw)
if err != nil {
return nil, err
}
orgCA := &SM2CA{
Name: orgCfg.Name,
Signer: signer,
SignCert: utils.ParseX509CertificateToSm2(cert),
CertConfig: orgCfg,
}
return orgCA, nil
}
// GenerateLocalUser 生成本地用户
func (ca *SM2CA) GenerateLocalUser(baseDir, fileName string) error {
err := createFolderStructure(baseDir, false)
if err != nil {
return err
}
keystore := filepath.Join(baseDir, "keystore")
priv, _, err := utils.GeneratePrivateKey(keystore, csp.SM2P256KygGen)
if err != nil {
return err
}
sm2PubKey, err := utils.GetSM2PublicKey(priv)
if err != nil {
return err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), fileName, []string{}, sm2PubKey, false)
if err != nil || cert == nil {
return err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(ca.Name)), ca.SignCert.Raw)
return err
}
func genCertificateGMSM2(baseDir, fileName string, template, parent *sm2.Certificate, key crypto.Signer) (*sm2.Certificate, error) {
certBytes, err := utils.CreateCertificateToMem(template, parent, key)
if err != nil {
return nil, err
}
fullName := filepath.Join(baseDir, fileName+"-cert.pem")
err = utils.CreateCertificateToPem(fullName, template, parent, key)
if err != nil {
return nil, err
}
x509Cert, err := sm2.ReadCertificateFromMem(certBytes)
if err != nil {
return nil, err
}
return x509Cert, nil
}
func createFolderStructure(rootDir string, isOrg bool) error {
var folders = []string{
filepath.Join(rootDir, "cacerts"),
filepath.Join(rootDir, "keystore"),
filepath.Join(rootDir, "signcerts"),
}
if isOrg {
folders = append(folders, filepath.Join(rootDir, "intermediatecerts"),)
}
for _, folder := range folders {
err := os.MkdirAll(folder, 0750)
if err != nil {
return err
}
}
return nil
}
func x509Filename(name string) string {
return name + "-cert.pem"
}
func x509Export(path string, cert []byte) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package impl
import (
"crypto"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"time"
"path/filepath"
"fmt"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/factory/csp"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator"
"github.com/33cn/plugin/plugin/dapp/cert/authority/tools/cryptogen/generator/utils"
ty "github.com/33cn/plugin/plugin/dapp/cert/types"
"github.com/tjfoc/gmsm/sm2"
)
// EcdsaCA ecdsa CA结构
type EcdsaCA struct {
Name string
Signer crypto.Signer
SignCert *x509.Certificate
}
// SM2CA SM2 CA结构
type SM2CA struct {
Name string
Signer crypto.Signer
SignCert *sm2.Certificate
Sm2Key csp.Key
}
// NewCA 根据类型生成CA生成器
func NewCA(baseDir, name string, signType int) (generator.CAGenerator, error) {
if signType == ty.AuthECDSA {
return newEcdsaCA(baseDir, name)
} else if signType == ty.AuthSM2 {
return newSM2CA(baseDir, name)
} else {
return nil, fmt.Errorf("Invalid sign type")
}
}
func newEcdsaCA(baseDir, name string) (*EcdsaCA, error) {
err := os.MkdirAll(baseDir, 0750)
if err != nil {
return nil, err
}
var ca *EcdsaCA
priv, signer, err := utils.GeneratePrivateKey(baseDir, csp.ECDSAP256KeyGen)
if err != nil {
return nil, err
}
ecPubKey, err := utils.GetECPublicKey(priv)
if err != nil {
return nil, err
}
template := x509Template()
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
subject := subjectTemplate()
subject.CommonName = name
template.Subject = subject
template.SubjectKeyId = priv.SKI()
template.PublicKey = ecPubKey
x509Cert, err := genCertificateECDSA(baseDir, name, &template, &template, signer)
if err != nil {
return nil, err
}
ca = &EcdsaCA{
Name: name,
Signer: signer,
SignCert: x509Cert,
}
return ca, nil
}
// SignCertificate 证书签名
func (ca *EcdsaCA) SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error) {
template := x509Template()
template.KeyUsage = x509.KeyUsageDigitalSignature
template.ExtKeyUsage = []x509.ExtKeyUsage{}
subject := subjectTemplate()
subject.CommonName = name
template.Subject = subject
template.DNSNames = sans
template.PublicKey = pub
cert, err := genCertificateECDSA(baseDir, name, &template, ca.SignCert, ca.Signer)
if err != nil {
return nil, err
}
return cert, nil
}
// GenerateLocalUser 生成本地用户
func (ca *EcdsaCA) GenerateLocalUser(baseDir, name string) error {
err := createFolderStructure(baseDir, true)
if err != nil {
return err
}
keystore := filepath.Join(baseDir, "keystore")
priv, _, err := utils.GeneratePrivateKey(keystore, csp.ECDSAP256KeyGen)
if err != nil {
return err
}
ecPubKey, err := utils.GetECPublicKey(priv)
if err != nil {
return err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), name, []string{}, ecPubKey)
if err != nil || cert == nil {
return err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(ca.Name)), ca.SignCert.Raw)
return err
}
func subjectTemplate() pkix.Name {
return pkix.Name{
Country: []string{"US"},
Locality: []string{"San Francisco"},
Province: []string{"California"},
}
}
func x509Template() x509.Certificate {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
expiry := 3650 * 24 * time.Hour
notBefore := time.Now().Add(-5 * time.Minute).UTC()
x509 := x509.Certificate{
SerialNumber: serialNumber,
NotBefore: notBefore,
NotAfter: notBefore.Add(expiry).UTC(),
BasicConstraintsValid: true,
}
return x509
}
func genCertificateECDSA(baseDir, name string, template, parent *x509.Certificate, priv interface{}) (*x509.Certificate, error) {
certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, template.PublicKey, priv)
if err != nil {
return nil, err
}
fileName := filepath.Join(baseDir, name+"-cert.pem")
certFile, err := os.Create(fileName)
if err != nil {
return nil, err
}
defer certFile.Close()
err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
if err != nil {
return nil, err
}
x509Cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, err
}
return x509Cert, nil
}
func newSM2CA(baseDir, name string) (*SM2CA, error) {
var ca *SM2CA
priv, signer, err := utils.GeneratePrivateKey(baseDir, csp.SM2P256KygGen)
if err != nil {
return nil, err
}
smPubKey, err := utils.GetSM2PublicKey(priv)
if err != nil {
return nil, err
}
template := x509Template()
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
subject := subjectTemplate()
subject.CommonName = name
template.Subject = subject
template.SubjectKeyId = priv.SKI()
sm2cert := utils.ParseX509CertificateToSm2(&template)
sm2cert.PublicKey = smPubKey
x509Cert, err := genCertificateGMSM2(baseDir, name, sm2cert, sm2cert, signer)
if err == nil {
ca = &SM2CA{
Name: name,
Signer: signer,
SignCert: x509Cert,
Sm2Key: priv,
}
}
return ca, nil
}
// SignCertificate 证书签名
func (ca *SM2CA) SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error) {
template := x509Template()
template.KeyUsage = x509.KeyUsageDigitalSignature
template.ExtKeyUsage = []x509.ExtKeyUsage{}
subject := subjectTemplate()
subject.CommonName = name
template.Subject = subject
template.DNSNames = sans
template.PublicKey = pub
sm2Tpl := utils.ParseX509CertificateToSm2(&template)
cert, err := genCertificateGMSM2(baseDir, name, sm2Tpl, ca.SignCert, ca.Signer)
if err != nil {
return nil, err
}
return utils.ParseSm2CertificateToX509(cert), nil
}
// GenerateLocalUser 生成本地用户
func (ca *SM2CA) GenerateLocalUser(baseDir, name string) error {
err := createFolderStructure(baseDir, true)
if err != nil {
return err
}
keystore := filepath.Join(baseDir, "keystore")
priv, _, err := utils.GeneratePrivateKey(keystore, csp.SM2P256KygGen)
if err != nil {
return err
}
sm2PubKey, err := utils.GetSM2PublicKey(priv)
if err != nil {
return err
}
cert, err := ca.SignCertificate(filepath.Join(baseDir, "signcerts"), name, []string{}, sm2PubKey)
if err != nil || cert == nil {
return err
}
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(ca.Name)), ca.SignCert.Raw)
return err
}
func genCertificateGMSM2(baseDir, name string, template, parent *sm2.Certificate, key crypto.Signer) (*sm2.Certificate, error) {
certBytes, err := utils.CreateCertificateToMem(template, parent, key)
if err != nil {
return nil, err
}
fileName := filepath.Join(baseDir, name+"-cert.pem")
err = utils.CreateCertificateToPem(fileName, template, parent, key)
if err != nil {
return nil, err
}
x509Cert, err := sm2.ReadCertificateFromMem(certBytes)
if err != nil {
return nil, err
}
return x509Cert, nil
}
func createFolderStructure(rootDir string, local bool) error {
var folders = []string{
filepath.Join(rootDir, "cacerts"),
}
if local {
folders = append(folders, filepath.Join(rootDir, "keystore"),
filepath.Join(rootDir, "signcerts"))
}
for _, folder := range folders {
err := os.MkdirAll(folder, 0750)
if err != nil {
return err
}
}
return nil
}
func x509Filename(name string) string {
return name + "-cert.pem"
}
func x509Export(path string, cert []byte) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
}
...@@ -24,7 +24,7 @@ func Init(name string, cfg *types.Chain33Config, sub []byte) { ...@@ -24,7 +24,7 @@ func Init(name string, cfg *types.Chain33Config, sub []byte) {
} }
err := authority.Author.Init(&scfg) err := authority.Author.Init(&scfg)
if err != nil { if err != nil {
clog.Error("error to initialize authority", err) clog.Error("error to initialize authority", "error", err)
return return
} }
drivers.Register(cfg, driverName, newCert, cfg.GetDappFork(driverName, "Enable")) drivers.Register(cfg, driverName, newCert, cfg.GetDappFork(driverName, "Enable"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment