github.com/turingchain2020/turingchain@v1.1.21/executor/authority/core/gmimpl.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 core 6 7 import ( 8 "bytes" 9 "crypto/ecdsa" 10 "crypto/x509/pkix" 11 "encoding/asn1" 12 "encoding/pem" 13 "errors" 14 "fmt" 15 "math/big" 16 "reflect" 17 "time" 18 19 "github.com/turingchain2020/turingchain/executor/authority/utils" 20 21 sm2_util "github.com/turingchain2020/turingchain/system/crypto/sm2" 22 "github.com/turingchain2020/turingchain/types" 23 "github.com/tjfoc/gmsm/sm2" 24 ) 25 26 type gmValidator struct { 27 rootCerts []*sm2.Certificate 28 29 intermediateCerts []*sm2.Certificate 30 31 certificationTreeInternalNodesMap map[string]bool 32 33 opts *sm2.VerifyOptions 34 35 CRL []*pkix.CertificateList 36 } 37 38 // NewGmValidator 创建国密证书校验器 39 func NewGmValidator() Validator { 40 return &gmValidator{} 41 } 42 43 func (validator *gmValidator) getCertFromPem(idBytes []byte) (*sm2.Certificate, error) { 44 if idBytes == nil { 45 return nil, fmt.Errorf("getIdentityFromConf error: nil idBytes") 46 } 47 48 pemCert, _ := pem.Decode(idBytes) 49 if pemCert == nil { 50 return nil, fmt.Errorf("getIdentityFromBytes error: could not decode pem bytes [%v]", idBytes) 51 } 52 53 var cert *sm2.Certificate 54 cert, err := sm2.ParseCertificate(pemCert.Bytes) 55 if err != nil { 56 return nil, fmt.Errorf("getIdentityFromBytes error: failed to parse sm2 cert, err %s", err) 57 } 58 59 return cert, nil 60 } 61 62 func (validator *gmValidator) Setup(conf *AuthConfig) error { 63 if conf == nil { 64 return fmt.Errorf("Setup error: nil conf reference") 65 } 66 67 if err := validator.setupCAs(conf); err != nil { 68 return err 69 } 70 71 if err := validator.setupCRLs(conf); err != nil { 72 return err 73 } 74 75 if err := validator.finalizeSetupCAs(conf); err != nil { 76 return err 77 } 78 79 return nil 80 } 81 82 func (validator *gmValidator) Validate(certByte []byte, pubKey []byte) error { 83 authLogger.Debug("validating certificate") 84 85 cert, err := validator.getCertFromPem(certByte) 86 if err != nil { 87 return fmt.Errorf("ParseCertificate failed %s", err) 88 } 89 90 certPubKey, ok := cert.PublicKey.(*ecdsa.PublicKey) 91 if !ok { 92 return fmt.Errorf("Error publick key type in transaction. expect SM2") 93 } 94 95 if !bytes.Equal(pubKey, sm2_util.SerializePublicKey( 96 ParseECDSAPubKey2SM2PubKey(certPubKey), len(pubKey) == sm2_util.SM2PublicKeyCompressed)) { 97 return fmt.Errorf("Invalid public key") 98 } 99 100 validationChain, err := validator.getCertificationChain(cert) 101 if err != nil { 102 return fmt.Errorf("Could not obtain certification chain, err %s", err) 103 } 104 105 err = validator.validateCertAgainstChain(cert.SerialNumber, validationChain) 106 if err != nil { 107 return fmt.Errorf("Could not validate identity against certification chain, err %s", err) 108 } 109 110 return nil 111 } 112 113 func (validator *gmValidator) getCertificationChain(cert *sm2.Certificate) ([]*sm2.Certificate, error) { 114 if validator.opts == nil { 115 return nil, errors.New("Invalid validator instance") 116 } 117 118 if cert.IsCA { 119 return nil, errors.New("A CA certificate cannot be used directly by this validator") 120 } 121 122 return validator.getValidationChain(cert, false) 123 } 124 125 func (validator *gmValidator) getUniqueValidationChain(cert *sm2.Certificate, opts sm2.VerifyOptions) ([]*sm2.Certificate, error) { 126 if validator.opts == nil { 127 return nil, fmt.Errorf("The supplied identity has no verify options") 128 } 129 130 validationChains, err := cert.Verify(opts) 131 if err != nil { 132 return nil, fmt.Errorf("The supplied identity is not valid, Verify() returned %s", err) 133 } 134 135 if len(validationChains) != 1 { 136 return nil, fmt.Errorf("This validator only supports a single validation chain, got %d", len(validationChains)) 137 } 138 139 return validationChains[0], nil 140 } 141 142 func (validator *gmValidator) getValidationChain(cert *sm2.Certificate, isIntermediateChain bool) ([]*sm2.Certificate, error) { 143 validationChain, err := validator.getUniqueValidationChain(cert, validator.getValidityOptsForCert(cert)) 144 if err != nil { 145 return nil, fmt.Errorf("Failed getting validation chain %s", err) 146 } 147 148 if len(validationChain) < 2 { 149 return nil, fmt.Errorf("Expected a chain of length at least 2, got %d", len(validationChain)) 150 } 151 152 parentPosition := 1 153 if isIntermediateChain { 154 parentPosition = 0 155 } 156 if validator.certificationTreeInternalNodesMap[string(validationChain[parentPosition].Raw)] { 157 return nil, fmt.Errorf("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v]", cert.Raw) 158 } 159 return validationChain, nil 160 } 161 162 func (validator *gmValidator) setupCAs(conf *AuthConfig) error { 163 if len(conf.RootCerts) == 0 { 164 return errors.New("Expected at least one CA certificate") 165 } 166 167 validator.opts = &sm2.VerifyOptions{Roots: sm2.NewCertPool(), Intermediates: sm2.NewCertPool()} 168 for _, v := range conf.RootCerts { 169 cert, err := validator.getCertFromPem(v) 170 if err != nil { 171 return err 172 } 173 validator.opts.Roots.AddCert(cert) 174 } 175 for _, v := range conf.IntermediateCerts { 176 cert, err := validator.getCertFromPem(v) 177 if err != nil { 178 return err 179 } 180 validator.opts.Intermediates.AddCert(cert) 181 } 182 183 validator.rootCerts = make([]*sm2.Certificate, len(conf.RootCerts)) 184 for i, trustedCert := range conf.RootCerts { 185 cert, err := validator.getCertFromPem(trustedCert) 186 if err != nil { 187 return err 188 } 189 190 validator.rootCerts[i] = cert 191 } 192 193 validator.intermediateCerts = make([]*sm2.Certificate, len(conf.IntermediateCerts)) 194 for i, trustedCert := range conf.IntermediateCerts { 195 cert, err := validator.getCertFromPem(trustedCert) 196 if err != nil { 197 return err 198 } 199 200 validator.intermediateCerts[i] = cert 201 } 202 203 validator.opts = &sm2.VerifyOptions{Roots: sm2.NewCertPool(), Intermediates: sm2.NewCertPool()} 204 for _, cert := range validator.rootCerts { 205 validator.opts.Roots.AddCert(cert) 206 } 207 for _, cert := range validator.intermediateCerts { 208 validator.opts.Intermediates.AddCert(cert) 209 } 210 211 return nil 212 } 213 214 func (validator *gmValidator) setupCRLs(conf *AuthConfig) error { 215 validator.CRL = make([]*pkix.CertificateList, len(conf.RevocationList)) 216 for i, crlbytes := range conf.RevocationList { 217 crl, err := sm2.ParseCRL(crlbytes) 218 if err != nil { 219 return fmt.Errorf("Could not parse RevocationList, err %s", err) 220 } 221 222 validator.CRL[i] = crl 223 } 224 225 return nil 226 } 227 228 func (validator *gmValidator) finalizeSetupCAs(config *AuthConfig) error { 229 for _, cert := range append(append([]*sm2.Certificate{}, validator.rootCerts...), validator.intermediateCerts...) { 230 if !isSm2CACert(cert) { 231 return fmt.Errorf("CA Certificate did not have the Subject Key Identifier extension, (SN: %s)", cert.SerialNumber) 232 } 233 234 if err := validator.validateCAIdentity(cert); err != nil { 235 return fmt.Errorf("CA Certificate is not valid, (SN: %s) [%s]", cert.SerialNumber, err) 236 } 237 } 238 239 validator.certificationTreeInternalNodesMap = make(map[string]bool) 240 for _, cert := range append([]*sm2.Certificate{}, validator.intermediateCerts...) { 241 chain, err := validator.getUniqueValidationChain(cert, validator.getValidityOptsForCert(cert)) 242 if err != nil { 243 return fmt.Errorf("Failed getting validation chain, (SN: %s)", cert.SerialNumber) 244 } 245 246 for i := 1; i < len(chain); i++ { 247 validator.certificationTreeInternalNodesMap[string(chain[i].Raw)] = true 248 } 249 } 250 251 return nil 252 } 253 254 func getSubjectKeyIdentifierFromSm2Cert(cert *sm2.Certificate) ([]byte, error) { 255 var SKI []byte 256 257 for _, ext := range cert.Extensions { 258 if reflect.DeepEqual(ext.Id, asn1.ObjectIdentifier{2, 5, 29, 14}) { 259 _, err := asn1.Unmarshal(ext.Value, &SKI) 260 if err != nil { 261 return nil, fmt.Errorf("Failed to unmarshal Subject Key Identifier, err %s", err) 262 } 263 264 return SKI, nil 265 } 266 } 267 268 return nil, errors.New("subjectKeyIdentifier not found in certificate") 269 } 270 271 func isSm2CACert(cert *sm2.Certificate) bool { 272 _, err := getSubjectKeyIdentifierFromSm2Cert(cert) 273 if err != nil { 274 return false 275 } 276 277 if !cert.IsCA { 278 return false 279 } 280 281 return true 282 } 283 284 func (validator *gmValidator) validateCAIdentity(cert *sm2.Certificate) error { 285 if !cert.IsCA { 286 return errors.New("Only CA identities can be validated") 287 } 288 289 validationChain, err := validator.getUniqueValidationChain(cert, validator.getValidityOptsForCert(cert)) 290 if err != nil { 291 return fmt.Errorf("Could not obtain certification chain, err %s", err) 292 } 293 if len(validationChain) == 1 { 294 return nil 295 } 296 297 return validator.validateCertAgainstChain(cert.SerialNumber, validationChain) 298 } 299 300 func (validator *gmValidator) validateCertAgainstChain(serialNumber *big.Int, validationChain []*sm2.Certificate) error { 301 SKI, err := getSubjectKeyIdentifierFromSm2Cert(validationChain[1]) 302 if err != nil { 303 return fmt.Errorf("Could not obtain Subject Key Identifier for signer cert, err %s", err) 304 } 305 306 for _, crl := range validator.CRL { 307 aki, err := getAuthorityKeyIdentifierFromCrl(crl) 308 if err != nil { 309 return fmt.Errorf("Could not obtain Authority Key Identifier for crl, err %s", err) 310 } 311 312 if bytes.Equal(aki, SKI) { 313 for _, rc := range crl.TBSCertList.RevokedCertificates { 314 if rc.SerialNumber.Cmp(serialNumber) == 0 { 315 err = validationChain[1].CheckCRLSignature(crl) 316 if err != nil { 317 authLogger.Warn(fmt.Sprintf("Invalid signature over the identified CRL, error %s", err)) 318 continue 319 } 320 321 return errors.New("The certificate has been revoked") 322 } 323 } 324 } 325 } 326 327 return nil 328 } 329 330 func (validator *gmValidator) getValidityOptsForCert(cert *sm2.Certificate) sm2.VerifyOptions { 331 var tempOpts sm2.VerifyOptions 332 tempOpts.Roots = validator.opts.Roots 333 334 tempOpts.DNSName = validator.opts.DNSName 335 tempOpts.Intermediates = validator.opts.Intermediates 336 tempOpts.KeyUsages = validator.opts.KeyUsages 337 tempOpts.CurrentTime = cert.NotBefore.Add(time.Second) 338 339 return tempOpts 340 } 341 342 func (validator *gmValidator) GetCertFromSignature(signature []byte) ([]byte, error) { 343 if len(signature) <= sm2_util.SM2SignatureMinLength { 344 authLogger.Error("invalid signature, please make sure certificate info encoded.") 345 return nil, types.ErrCertificate 346 } 347 348 // 从proto中解码signature 349 cert, err := utils.DecodeCertFromSignature(signature) 350 if err != nil { 351 authLogger.Error("unmashal certificate from signature failed.", "error", err.Error()) 352 return nil, err 353 } 354 355 if len(cert.Cert) == 0 { 356 authLogger.Error("cert can not be null") 357 return nil, types.ErrInvalidParam 358 } 359 360 return cert.Cert, nil 361 }