Skip to content

Commit 679b65a

Browse files
author
Ziqi Zhang
committed
Add support to deprecated CRL functions for go1.18
Move and separate version-sensitive functionalities related to CRL into two go files within the config package so that it can build with the corresponding go version. Signed-off-by: Ziqi Zhang <[email protected]>
1 parent e87d76c commit 679b65a

File tree

4 files changed

+157
-40
lines changed

4 files changed

+157
-40
lines changed

config/crl.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2016 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// This file is built for It provides functionalities to parse raw CRLs,
15+
// check their validity and verify their signatures against provided
16+
// certificates (CAs). It also allows checking the revocation status of the
17+
// provided certificates.
18+
19+
// It is built for Go versions after and include Go version 1.19 as there
20+
// are new functionality related to CRL handling.
21+
22+
//go:build go1.19
23+
// +build go1.19
24+
25+
package config
26+
27+
import (
28+
"crypto/x509"
29+
"encoding/pem"
30+
"fmt"
31+
"time"
32+
)
33+
34+
// Parse all CRLs and return a slice of valid CRLs.
35+
func parseCRLs(rawCRL []byte, cAs []*x509.Certificate) ([]*x509.RevocationList, error) {
36+
var crls []*x509.RevocationList
37+
for p, r := pem.Decode(rawCRL); p != nil; p, r = pem.Decode(r) {
38+
if p.Type != "X509 CRL" {
39+
return nil, fmt.Errorf("unable to decode raw certificate revocation list")
40+
}
41+
crl, err := x509.ParseRevocationList(p.Bytes)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
// Check CRL exipry status.
47+
if crl.NextUpdate.Before(time.Now()) {
48+
return nil, fmt.Errorf("certificate revocation list is outdated")
49+
}
50+
51+
// Check each CRL is signed by any CA, if not, ignore the CRL.
52+
// Otherwise, append to the valid slice of CRL.
53+
for _, ca := range cAs {
54+
err = crl.CheckSignatureFrom(ca)
55+
if err == nil {
56+
crls = append(crls, crl)
57+
break
58+
}
59+
}
60+
}
61+
return crls, nil
62+
}
63+
64+
func validRevocationStatus(cAs []*x509.Certificate, cRLs []*x509.RevocationList) error {
65+
for _, cert := range cAs {
66+
for _, crl := range cRLs {
67+
for _, revokedCertificate := range crl.RevokedCertificates {
68+
if revokedCertificate.SerialNumber.Cmp(cert.SerialNumber) == 0 {
69+
return fmt.Errorf("certificate was revoked")
70+
}
71+
}
72+
}
73+
}
74+
return nil
75+
}

config/crl_deprecated.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2016 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// This file is built for It provides functionalities to parse raw CRLs,
15+
// check their validity and verify their signatures against provided
16+
// certificates (CAs). It also allows checking the revocation status of the
17+
// provided certificates.
18+
19+
// It is built for Go versions before 1.19 as there are deprecated
20+
// functionality related to CRL handling.
21+
22+
//go:build !go1.19
23+
// +build !go1.19
24+
25+
package config
26+
27+
import (
28+
"crypto/x509"
29+
"crypto/x509/pkix"
30+
"encoding/pem"
31+
"fmt"
32+
"time"
33+
)
34+
35+
// Parse all CRLs and return a slice of valid CRLs.
36+
func parseCRLs(rawCRL []byte, cAs []*x509.Certificate) ([]*pkix.CertificateList, error) {
37+
var crls []*pkix.CertificateList
38+
for p, r := pem.Decode(rawCRL); p != nil; p, r = pem.Decode(r) {
39+
if p.Type != "X509 CRL" {
40+
return nil, fmt.Errorf("unable to decode raw certificate revocation list")
41+
}
42+
crl, err := x509.ParseCRL(p.Bytes)
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
// Check CRL exipry status.
48+
if crl.TBSCertList.NextUpdate.Before(time.Now()) {
49+
return nil, fmt.Errorf("certificate revocation list is outdated")
50+
}
51+
52+
// Check each CRL is signed by any CA, if not, ignore the CRL.
53+
// Otherwise, append to the valid slice of CRL.
54+
for _, ca := range cAs {
55+
err = ca.CheckCRLSignature(crl)
56+
if err == nil {
57+
crls = append(crls, crl)
58+
break
59+
}
60+
}
61+
}
62+
return crls, nil
63+
}
64+
65+
func validRevocationStatus(cAs []*x509.Certificate, cRLs []*pkix.CertificateList) error {
66+
for _, cert := range cAs {
67+
for _, crl := range cRLs {
68+
for _, revokedCertificate := range crl.TBSCertList.RevokedCertificates {
69+
if revokedCertificate.SerialNumber.Cmp(cert.SerialNumber) == 0 {
70+
return fmt.Errorf("certificate was revoked")
71+
}
72+
}
73+
}
74+
}
75+
return nil
76+
}

config/http_config.go

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,49 +1356,14 @@ func (c *TLSConfig) verifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]
13561356
// against valid CRLs.
13571357
cAs = append(cAs, verifiedChains[0][0])
13581358

1359-
for _, cert := range cAs {
1360-
for _, crl := range crlsList {
1361-
for _, revokedCertificate := range crl.RevokedCertificates {
1362-
if revokedCertificate.SerialNumber.Cmp(cert.SerialNumber) == 0 {
1363-
return fmt.Errorf("certificate was revoked")
1364-
}
1365-
}
1366-
}
1359+
err = validRevocationStatus(cAs, crlsList)
1360+
if err != nil {
1361+
return err
13671362
}
13681363

13691364
return nil
13701365
}
13711366

1372-
// Parse all CRLs and return a slice of valid CRLs.
1373-
func parseCRLs(rawCRL []byte, cAs []*x509.Certificate) ([]*x509.RevocationList, error) {
1374-
var crls []*x509.RevocationList
1375-
for p, r := pem.Decode(rawCRL); p != nil; p, r = pem.Decode(r) {
1376-
if p.Type != "X509 CRL" {
1377-
return nil, fmt.Errorf("unable to decode raw certificate revocation list")
1378-
}
1379-
crl, err := x509.ParseRevocationList(p.Bytes)
1380-
if err != nil {
1381-
return nil, err
1382-
}
1383-
1384-
// Check CRL exipry status.
1385-
if crl.NextUpdate.Before(time.Now()) {
1386-
return nil, fmt.Errorf("certificate revocation list is outdated")
1387-
}
1388-
1389-
// Check each CRL is signed by any CA, if not, ignore the CRL.
1390-
// Otherwise, append to the valid slice of CRL.
1391-
for _, ca := range cAs {
1392-
err = crl.CheckSignatureFrom(ca)
1393-
if err == nil {
1394-
crls = append(crls, crl)
1395-
break
1396-
}
1397-
}
1398-
}
1399-
return crls, nil
1400-
}
1401-
14021367
// Parse raw certificates with padding structure.
14031368
func parseCerts(rawCerts []byte) ([]*x509.Certificate, error) {
14041369
var certList []*x509.Certificate

config/http_config_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ func TestNewClientFromRevokedCertConfig(t *testing.T) {
21392139
handler: func(w http.ResponseWriter, r *http.Request) {
21402140
fmt.Fprint(w, ExpectedMessage)
21412141
},
2142-
}, { // Full chain of CA and the single root CA revoke the intermediate CA certificate.
2142+
}, { // Full chain of CA and CRL, the single root CA revoke the intermediate CA certificate.
21432143
clientConfig: HTTPClientConfig{
21442144
TLSConfig: TLSConfig{
21452145
CAFile: TLSCAChainPath,
@@ -2152,7 +2152,8 @@ func TestNewClientFromRevokedCertConfig(t *testing.T) {
21522152
handler: func(w http.ResponseWriter, r *http.Request) {
21532153
fmt.Fprint(w, ExpectedMessage)
21542154
},
2155-
}, { // Missing root in the CA Chain and the full chain of CRLs, the Intermediate CA revoke the peer certificate.
2155+
}, { // Missing root in the CA Chain and the full chain of CRLs,
2156+
// the Intermediate CA revoke the peer certificate.
21562157
clientConfig: HTTPClientConfig{
21572158
TLSConfig: TLSConfig{
21582159
CAFile: TLSCACHainNoRootPath,

0 commit comments

Comments
 (0)