github.com/turingchain2020/turingchain@v1.1.21/executor/authority/authority.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package authority 6 7 import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "path" 12 13 "github.com/turingchain2020/turingchain/common" 14 "github.com/turingchain2020/turingchain/executor/authority/core" 15 "github.com/turingchain2020/turingchain/executor/authority/utils" 16 17 "github.com/turingchain2020/turingchain/common/crypto" 18 log "github.com/turingchain2020/turingchain/common/log/log15" 19 "github.com/turingchain2020/turingchain/types" 20 ) 21 22 var ( 23 alog = log.New("module", "authority") 24 25 // Author 全局证书校验器 26 Author = &Authority{} 27 28 // IsAuthEnable 是否开启全局校验开关 29 IsAuthEnable = false 30 ) 31 32 // Authority 证书校验器主要结构 33 type Authority struct { 34 // 证书文件路径 35 cryptoPath string 36 // certByte缓存 37 authConfig *core.AuthConfig 38 // 校验器 39 validator core.Validator 40 // 签名类型 41 signType int 42 // 有效证书缓存 43 validCertCache [][]byte 44 // 历史证书缓存 45 HistoryCertCache *HistoryCertData 46 } 47 48 // HistoryCertData 历史变更记录 49 type HistoryCertData struct { 50 CryptoCfg *core.AuthConfig 51 CurHeight int64 52 NxtHeight int64 53 } 54 55 // Init 初始化auth 56 func (auth *Authority) Init(conf *types.AuthorityCfg) error { 57 if conf == nil || !conf.Enable { 58 return nil 59 } 60 61 if len(conf.CryptoPath) == 0 { 62 alog.Error("Crypto config path can not be null") 63 return types.ErrInvalidParam 64 } 65 auth.cryptoPath = conf.CryptoPath 66 67 sign := types.GetSignType("cert", conf.SignType) 68 if sign == types.Invalid { 69 alog.Error(fmt.Sprintf("Invalid sign type:%s", conf.SignType)) 70 return types.ErrInvalidParam 71 } 72 auth.signType = sign 73 74 authConfig, err := core.GetAuthConfig(conf.CryptoPath) 75 if err != nil { 76 alog.Error("Get authority crypto config failed") 77 return err 78 } 79 auth.authConfig = authConfig 80 81 vldt, err := core.GetLocalValidator(authConfig, auth.signType) 82 if err != nil { 83 alog.Error(fmt.Sprintf("Get loacal validator failed. err:%s", err.Error())) 84 return err 85 } 86 auth.validator = vldt 87 88 auth.validCertCache = make([][]byte, 0) 89 auth.HistoryCertCache = &HistoryCertData{authConfig, -1, -1} 90 91 IsAuthEnable = true 92 return nil 93 } 94 95 // newAuthConfig store数据转成authConfig数据 96 func newAuthConfig(store *types.HistoryCertStore) *core.AuthConfig { 97 ret := &core.AuthConfig{} 98 ret.RootCerts = make([][]byte, len(store.Rootcerts)) 99 for i, v := range store.Rootcerts { 100 ret.RootCerts[i] = append(ret.RootCerts[i], v...) 101 } 102 103 ret.IntermediateCerts = make([][]byte, len(store.IntermediateCerts)) 104 for i, v := range store.IntermediateCerts { 105 ret.IntermediateCerts[i] = append(ret.IntermediateCerts[i], v...) 106 } 107 108 ret.RevocationList = make([][]byte, len(store.RevocationList)) 109 for i, v := range store.RevocationList { 110 ret.RevocationList[i] = append(ret.RevocationList[i], v...) 111 } 112 113 return ret 114 } 115 116 // ReloadCert 从数据库中的记录数据恢复证书,用于证书回滚 117 func (auth *Authority) ReloadCert(store *types.HistoryCertStore) error { 118 if !IsAuthEnable { 119 return nil 120 } 121 122 //判断是否回滚到无证书区块 123 if len(store.Rootcerts) == 0 { 124 auth.authConfig = nil 125 auth.validator, _ = core.NewNoneValidator() 126 } else { 127 auth.authConfig = newAuthConfig(store) 128 // 加载校验器 129 vldt, err := core.GetLocalValidator(auth.authConfig, auth.signType) 130 if err != nil { 131 return err 132 } 133 auth.validator = vldt 134 } 135 136 // 清空有效证书缓存 137 auth.validCertCache = auth.validCertCache[:0] 138 139 // 更新最新历史数据 140 auth.HistoryCertCache = &HistoryCertData{auth.authConfig, store.CurHeigth, store.NxtHeight} 141 142 return nil 143 } 144 145 // ReloadCertByHeght 从新的authdir下的文件更新证书,用于证书更新 146 func (auth *Authority) ReloadCertByHeght(currentHeight int64) error { 147 if !IsAuthEnable { 148 return nil 149 } 150 151 authConfig, err := core.GetAuthConfig(auth.cryptoPath) 152 if err != nil { 153 alog.Error("Get authority crypto config failed") 154 return err 155 } 156 auth.authConfig = authConfig 157 158 // 加载校验器 159 vldt, err := core.GetLocalValidator(auth.authConfig, auth.signType) 160 if err != nil { 161 return err 162 } 163 auth.validator = vldt 164 165 // 清空有效证书缓存 166 auth.validCertCache = auth.validCertCache[:0] 167 168 // 更新最新历史数据 169 auth.HistoryCertCache = &HistoryCertData{auth.authConfig, currentHeight, -1} 170 171 return nil 172 } 173 174 // Validate 检验证书 175 func (auth *Authority) Validate(signature *types.Signature) error { 176 // 从proto中解码signature 177 cert, err := auth.validator.GetCertFromSignature(signature.Signature) 178 if err != nil { 179 return err 180 } 181 182 // 是否在有效证书缓存中 183 for _, v := range auth.validCertCache { 184 if bytes.Equal(v, cert) { 185 return nil 186 } 187 } 188 189 // 校验 190 err = auth.validator.Validate(cert, signature.GetPubkey()) 191 if err != nil { 192 alog.Error(fmt.Sprintf("validate cert failed. %s", err.Error())) 193 return fmt.Errorf("validate cert failed. error:%s", err.Error()) 194 } 195 auth.validCertCache = append(auth.validCertCache, cert) 196 197 return nil 198 } 199 200 // User 用户关联的证书私钥信息 201 type User struct { 202 ID string 203 Cert []byte 204 Key crypto.PrivKey 205 } 206 207 // UserLoader SKD加载user使用 208 type UserLoader struct { 209 configPath string 210 userMap map[string]*User 211 signType int 212 } 213 214 // Init userloader初始化 215 func (loader *UserLoader) Init(configPath string, signType string) error { 216 loader.configPath = configPath 217 loader.userMap = make(map[string]*User) 218 219 sign := types.GetSignType("cert", signType) 220 if sign == types.Invalid { 221 alog.Error(fmt.Sprintf("Invalid sign type:%s", signType)) 222 return types.ErrInvalidParam 223 } 224 loader.signType = sign 225 226 return loader.loadUsers() 227 } 228 229 func (loader *UserLoader) loadUsers() error { 230 certDir := path.Join(loader.configPath, "signcerts") 231 dir, err := ioutil.ReadDir(certDir) 232 if err != nil { 233 return err 234 } 235 236 keyDir := path.Join(loader.configPath, "keystore") 237 for _, file := range dir { 238 filePath := path.Join(certDir, file.Name()) 239 certBytes, err := utils.ReadFile(filePath) 240 if err != nil { 241 continue 242 } 243 244 ski, err := utils.GetPublicKeySKIFromCert(certBytes, loader.signType) 245 if err != nil { 246 alog.Error(err.Error()) 247 continue 248 } 249 filePath = path.Join(keyDir, ski+"_sk") 250 keyBytes, err := utils.ReadFile(filePath) 251 if err != nil { 252 continue 253 } 254 255 priv, err := loader.genCryptoPriv(keyBytes) 256 if err != nil { 257 alog.Error(fmt.Sprintf("Generate crypto private failed. error:%s", err.Error())) 258 continue 259 } 260 261 loader.userMap[file.Name()] = &User{file.Name(), certBytes, priv} 262 } 263 264 return nil 265 } 266 267 func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error) { 268 cr, err := crypto.New(types.GetSignName("cert", loader.signType)) 269 if err != nil { 270 return nil, fmt.Errorf("create crypto %s failed, error:%s", types.GetSignName("cert", loader.signType), err) 271 } 272 //privKeyByte, err := utils.PrivKeyByteFromRaw(keyBytes, loader.signType) 273 //if err != nil { 274 // return nil, err 275 //} 276 277 privkeyBytes, err := common.FromHex(string(keyBytes)) 278 if err != nil { 279 return nil, err 280 } 281 282 priv, err := cr.PrivKeyFromBytes(privkeyBytes) 283 if err != nil { 284 return nil, fmt.Errorf("get private key failed, error:%s", err) 285 } 286 287 return priv, nil 288 } 289 290 // Get 根据用户名获取user结构 291 func (loader *UserLoader) Get(userName, orgName string) (*User, error) { 292 keyvalue := fmt.Sprintf("%s@%s-cert.pem", userName, orgName) 293 user, ok := loader.userMap[keyvalue] 294 if !ok { 295 return nil, types.ErrInvalidParam 296 } 297 298 resp := &User{} 299 resp.Cert = append(resp.Cert, user.Cert...) 300 resp.Key = user.Key 301 302 return resp, nil 303 }