|
@@ -15,9 +15,10 @@
|
|
package common
|
|
package common
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "bytes"
|
|
"crypto/tls"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509"
|
|
- "crypto/x509/pkix"
|
|
|
|
|
|
+ "encoding/pem"
|
|
"errors"
|
|
"errors"
|
|
"fmt"
|
|
"fmt"
|
|
"io/fs"
|
|
"io/fs"
|
|
@@ -25,7 +26,6 @@ import (
|
|
"os"
|
|
"os"
|
|
"path/filepath"
|
|
"path/filepath"
|
|
"sync"
|
|
"sync"
|
|
- "time"
|
|
|
|
|
|
|
|
"github.com/drakkan/sftpgo/v2/internal/logger"
|
|
"github.com/drakkan/sftpgo/v2/internal/logger"
|
|
"github.com/drakkan/sftpgo/v2/internal/util"
|
|
"github.com/drakkan/sftpgo/v2/internal/util"
|
|
@@ -34,10 +34,12 @@ import (
|
|
const (
|
|
const (
|
|
// DefaultTLSKeyPaidID defines the id to use for non-binding specific key pairs
|
|
// DefaultTLSKeyPaidID defines the id to use for non-binding specific key pairs
|
|
DefaultTLSKeyPaidID = "default"
|
|
DefaultTLSKeyPaidID = "default"
|
|
|
|
+ pemCRLType = "X509 CRL"
|
|
)
|
|
)
|
|
|
|
|
|
var (
|
|
var (
|
|
certAutoReload bool
|
|
certAutoReload bool
|
|
|
|
+ pemCRLPrefix = []byte("-----BEGIN X509 CRL")
|
|
)
|
|
)
|
|
|
|
|
|
// SetCertAutoReloadMode sets if the certificate must be monitored for changes and
|
|
// SetCertAutoReloadMode sets if the certificate must be monitored for changes and
|
|
@@ -66,7 +68,7 @@ type CertManager struct {
|
|
certs map[string]*tls.Certificate
|
|
certs map[string]*tls.Certificate
|
|
certsInfo map[string]fs.FileInfo
|
|
certsInfo map[string]fs.FileInfo
|
|
rootCAs *x509.CertPool
|
|
rootCAs *x509.CertPool
|
|
- crls []*pkix.CertificateList
|
|
|
|
|
|
+ crls []*x509.RevocationList
|
|
}
|
|
}
|
|
|
|
|
|
// Reload tries to reload certificate and CRLs
|
|
// Reload tries to reload certificate and CRLs
|
|
@@ -139,8 +141,8 @@ func (m *CertManager) IsRevoked(crt *x509.Certificate, caCrt *x509.Certificate)
|
|
}
|
|
}
|
|
|
|
|
|
for _, crl := range m.crls {
|
|
for _, crl := range m.crls {
|
|
- if !crl.HasExpired(time.Now()) && caCrt.CheckCRLSignature(crl) == nil { //nolint:staticcheck
|
|
|
|
- for _, rc := range crl.TBSCertList.RevokedCertificates {
|
|
|
|
|
|
+ if crl.CheckSignatureFrom(caCrt) == nil {
|
|
|
|
+ for _, rc := range crl.RevokedCertificates {
|
|
if rc.SerialNumber.Cmp(crt.SerialNumber) == 0 {
|
|
if rc.SerialNumber.Cmp(crt.SerialNumber) == 0 {
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
@@ -157,7 +159,7 @@ func (m *CertManager) LoadCRLs() error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
- var crls []*pkix.CertificateList
|
|
|
|
|
|
+ var crls []*x509.RevocationList
|
|
|
|
|
|
for _, revocationList := range m.caRevocationLists {
|
|
for _, revocationList := range m.caRevocationLists {
|
|
if !util.IsFileInputValid(revocationList) {
|
|
if !util.IsFileInputValid(revocationList) {
|
|
@@ -171,7 +173,13 @@ func (m *CertManager) LoadCRLs() error {
|
|
logger.Warn(m.logSender, "", "unable to read revocation list %q", revocationList)
|
|
logger.Warn(m.logSender, "", "unable to read revocation list %q", revocationList)
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- crl, err := x509.ParseCRL(crlBytes) //nolint:staticcheck
|
|
|
|
|
|
+ if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
|
|
|
|
+ block, _ := pem.Decode(crlBytes)
|
|
|
|
+ if block != nil && block.Type == pemCRLType {
|
|
|
|
+ crlBytes = block.Bytes
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ crl, err := x509.ParseRevocationList(crlBytes)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.Warn(m.logSender, "", "unable to parse revocation list %q", revocationList)
|
|
logger.Warn(m.logSender, "", "unable to parse revocation list %q", revocationList)
|
|
return err
|
|
return err
|