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