| 363 | } |
| 364 | |
| 365 | func verifyCRL(crl *CRL, chain []*x509.Certificate) error { |
| 366 | // RFC5280, 6.3.3 (f) Obtain and validate the certification path for the issuer of the complete CRL |
| 367 | // We intentionally limit our CRLs to be signed with the same certificate path as the certificate |
| 368 | // so we can use the chain from the connection. |
| 369 | |
| 370 | for _, c := range chain { |
| 371 | // Use the key where the subject and KIDs match. |
| 372 | // This departs from RFC4158, 3.5.12 which states that KIDs |
| 373 | // cannot eliminate certificates, but RFC5280, 5.2.1 states that |
| 374 | // "Conforming CRL issuers MUST use the key identifier method, and MUST |
| 375 | // include this extension in all CRLs issued." |
| 376 | // So, this is much simpler than RFC4158 and should be compatible. |
| 377 | if bytes.Equal(c.SubjectKeyId, crl.authorityKeyID) && bytes.Equal(c.RawSubject, crl.rawIssuer) { |
| 378 | // RFC5280, 6.3.3 (f) Key usage and cRLSign bit. |
| 379 | if c.KeyUsage != 0 && c.KeyUsage&x509.KeyUsageCRLSign == 0 { |
| 380 | return fmt.Errorf("verifyCRL: The certificate can't be used for issuing CRLs") |
| 381 | } |
| 382 | // RFC5280, 6.3.3 (g) Validate signature. |
| 383 | return crl.certList.CheckSignatureFrom(c) |
| 384 | } |
| 385 | } |
| 386 | return fmt.Errorf("verifyCRL: No certificates matched CRL issuer (%v)", crl.certList.Issuer) |
| 387 | } |
| 388 | |
| 389 | // pemType is the type of a PEM encoded CRL. |
| 390 | const pemType string = "X509 CRL" |