diff --git a/crl/crlreader/extensionsupport/extensionsupport.go b/crl/crlreader/extensionsupport/extensionsupport.go index 6cae710..13e73c7 100644 --- a/crl/crlreader/extensionsupport/extensionsupport.go +++ b/crl/crlreader/extensionsupport/extensionsupport.go @@ -1,13 +1,10 @@ package extensionsupport import ( - "bufio" - "bytes" "crypto/x509/pkix" "encoding/asn1" "errors" "fmt" - "github.com/gr33nbl00d/caddy-revocation-validator/core/asn1parser" "math/big" ) @@ -31,35 +28,6 @@ type GeneralName struct { RegisteredID asn1.RawValue `asn1:"tag:8,optional"` } -func (G GeneralName) GetGeneralNameType() (int, error) { - reader := bufio.NewReader(bytes.NewReader(G.Raw)) - tagLength, err := asn1parser.PeekTagLength(reader, 0) - if err != nil { - return 0, err - } - if asn1parser.IsContextSpecificTag(tagLength) == false { - return -1, errors.New("generalname content is invalid") - } - lastContextSpecificTag, err := findLastRecursiveContextSpecificTagInOrder(nil, reader, 0) - if err != nil { - return 0, err - } - return asn1parser.GetContextSpecificTagId(lastContextSpecificTag), nil -} - -func findLastRecursiveContextSpecificTagInOrder(previous *asn1parser.TagLength, reader *bufio.Reader, offset int) (*asn1parser.TagLength, error) { - //this coding is needed because asn1 parser of go has wrong handling of multiple nested optional fields. - //in this case rawcontent is not the content of the struct but content from the last parent sequence - tagLength, err := asn1parser.PeekTagLength(reader, offset) - if err != nil { - return nil, err - } - if asn1parser.IsContextSpecificTag(tagLength) { - return findLastRecursiveContextSpecificTagInOrder(tagLength, reader, offset+int(tagLength.CalculateTLLength().Int64())) - } - return previous, nil -} - const OidCertExtSubjectKeyId = "2.5.29.14" const OidCertExtAuthorityKeyId = "2.5.29.35" const OidCrlExtCrlNumber = "2.5.29.20" diff --git a/crl/crlreader/extensionsupport/extensionsupport_test.go b/crl/crlreader/extensionsupport/extensionsupport_test.go new file mode 100644 index 0000000..13a0ca4 --- /dev/null +++ b/crl/crlreader/extensionsupport/extensionsupport_test.go @@ -0,0 +1,101 @@ +package extensionsupport + +import ( + "crypto/x509/pkix" + "github.com/stretchr/testify/suite" + "testing" +) + +type ExtensionsupportTestSuite struct { + suite.Suite +} + +// Helper function to create a pkix.Extension with the given OID and critical flag +func newExtension(oid []int, critical bool) pkix.Extension { + return pkix.Extension{ + Id: oid, + Critical: critical, + } +} + +// Helper function to convert OID string into []int +func parseOID(oid string) []int { + parts := make([]int, 0) + for i := 0; i < len(oid); i++ { + if oid[i] == '.' { + continue + } + j := i + for j < len(oid) && oid[j] != '.' { + j++ + } + val := 0 + for k := i; k < j; k++ { + val = val*10 + int(oid[k]-'0') + } + parts = append(parts, val) + i = j - 1 + } + return parts +} + +func (suite *ExtensionsupportTestSuite) TestCheckForCriticalUnhandledCRLExtensions_NoCriticalExtensions() { + extensions := []pkix.Extension{ + newExtension(parseOID("1.2.3.4.5"), false), + newExtension(parseOID("1.2.3.4.6"), false), + } + + err := CheckForCriticalUnhandledCRLExtensions(&extensions) + suite.Require().NoError(err) +} + +func (suite *ExtensionsupportTestSuite) TestCheckForCriticalUnhandledCRLExtensions_KnownCriticalExtensions() { + extensions := []pkix.Extension{ + newExtension(parseOID("2.5.29.35"), true), // Authority Key Identifier + newExtension(parseOID("2.5.29.20"), false), // CRL Number + } + + err := CheckForCriticalUnhandledCRLExtensions(&extensions) + suite.Require().NoError(err) +} + +func (suite *ExtensionsupportTestSuite) TestCheckForCriticalUnhandledCRLExtensions_UnhandledCriticalExtensions() { + extensions := []pkix.Extension{ + newExtension(parseOID("2.5.29.27"), true), // Delta CRL Indicator + newExtension(parseOID("1.3.6.1.5.5.7.1.1"), false), // Authority Information Access + } + + err := CheckForCriticalUnhandledCRLExtensions(&extensions) + suite.Require().Error(err) + suite.Require().Equal("unhandled critical crl extension 2.5.29.27", err.Error()) +} + +// Test method for FindExtension +func (suite *ExtensionsupportTestSuite) TestFindExtension() { + extensions := []pkix.Extension{ + newExtension(parseOID("2.5.29.35"), true), // Authority Key Identifier + newExtension(parseOID("2.5.29.20"), false), // CRL Number + newExtension(parseOID("1.3.6.1.5.5.7.1.1"), false), // Authority Information Access + } + + // Test finding an existing extension + oidToFind := "2.5.29.35" + extension := FindExtension(oidToFind, &extensions) + suite.Require().NotNil(extension) + suite.Require().Equal(oidToFind, extension.Id.String()) + + // Test finding a non-existent extension + oidToFind = "1.2.3.4.5" + extension = FindExtension(oidToFind, &extensions) + suite.Require().Nil(extension) + + // Test with an empty list of extensions + extensions = []pkix.Extension{} + oidToFind = "2.5.29.35" + extension = FindExtension(oidToFind, &extensions) + suite.Require().Nil(extension) +} + +func TestExtensionsupportTestSuite(t *testing.T) { + suite.Run(t, new(ExtensionsupportTestSuite)) +}