diff --git a/pem/pem_reader.go b/pem/pem_reader.go deleted file mode 100644 index 0b6d6c9..0000000 --- a/pem/pem_reader.go +++ /dev/null @@ -1,82 +0,0 @@ -package pem - -import ( - "encoding/pem" - "os" -) - -// ParseFileOrPath processes a file or directory at the given path and extracts PEM blocks of the specified pemType. -func ParseFileOrPath(path string, pemType string) ([][]byte, error) { - fileInfo, err := os.Stat(path) - if err != nil { - return nil, err - } - if fileInfo.IsDir() { - files := make([][]byte, 0) - dir, err := os.ReadDir(path) - if err != nil { - return nil, nil - } - for _, file := range dir { - if file.IsDir() { - continue - } - blocks, err := readFile(path+"/"+file.Name(), pemType) - if err != nil { - return nil, err - } - files = append(files, blocks...) - } - return files, nil - } else { - blocks, err := readFile(path, pemType) - return blocks, err - } - -} - -// readFile reads a file from the given filename, parses it for PEM blocks of the specified type, and returns the blocks. -func readFile(filename string, pemType string) ([][]byte, error) { - files := make([][]byte, 0) - content, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - if looksLineCert(content, pemType) { - foundBlocks := ParsePemBlocks(content, pemType) - files = append(files, foundBlocks...) - } - return files, nil -} - -// ParsePemBlocks extracts specified PEM blocks from the provided certificate bytes and returns them as a pointer to a slice of byte slices. -func ParsePemBlocks(cert []byte, pemType string) [][]byte { - blocks := make([][]byte, 0) - for { - pemBlock, tail := pem.Decode(cert) - if pemBlock == nil { - break - } - if pemBlock.Type == pemType { - blocks = append(blocks, pemBlock.Bytes) - } - if tail == nil { - break - } - cert = tail - - } - return blocks -} - -// looksLineCert checks if the given certificate data is a valid PEM block of the specified type. -func looksLineCert(cert []byte, pemType string) bool { - pemBlock, _ := pem.Decode(cert) - if pemBlock == nil { - return false - } - if pemBlock.Type != pemType { - return false - } - return true -} diff --git a/pem/pem_reader_test.go b/pem/pem_reader_test.go deleted file mode 100644 index b41a4c3..0000000 --- a/pem/pem_reader_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package pem - -import ( - "encoding/base64" - "github.com/nuts-foundation/uzi-did-x509-issuer/x509_cert" - "github.com/stretchr/testify/assert" - "log" - "os" - "strings" - "testing" -) - -func TestParseFileOrPath(t *testing.T) { - tempFile, _ := os.CreateTemp("", "test") - defer func(name string) { - err := os.Remove(name) - if err != nil { - log.Fatal(err) - } - }(tempFile.Name()) - pemType := "CERTIFICATE" - - t.Run("FileExistsAndIsNotDirectory", func(t *testing.T) { - result, err := ParseFileOrPath(tempFile.Name(), pemType) - failError(t, err) - assert.NotNil(t, result) - }) - - t.Run("FileDoesNotExist", func(t *testing.T) { - _, err := ParseFileOrPath("nonexistent", pemType) - assert.Error(t, err) - }) - - tempDir, _ := os.MkdirTemp("", "testdir") - defer func(path string) { - err := os.RemoveAll(path) - if err != nil { - log.Fatal(err) - } - }(tempDir) - - t.Run("PathIsDirectory", func(t *testing.T) { - _, err := ParseFileOrPath(tempDir, pemType) - failError(t, err) - }) - - t.Run("PathDoesNotExist", func(t *testing.T) { - _, err := ParseFileOrPath("nonexistent/path", pemType) - assert.Error(t, err) - }) - t.Run("Happy flow single file", func(t *testing.T) { - file, err := os.CreateTemp(tempDir, "prefix") - if err != nil { - t.Fatal(err) - } - defer func(name string) { - err := os.Remove(name) - if err != nil { - log.Fatal(err) - } - }(file.Name()) - certs, chainPem, _, _, _, err := x509_cert.BuildSelfSignedCertChain("A BIG STRING", "a small one") - failError(t, err) - for i := 0; i < chainPem.Len(); i++ { - certBlock, ok := chainPem.Get(i) - certAsString := convertToString(certBlock) - if ok { - _, err := file.WriteString(certAsString) - if err != nil { - t.Fatal(err) - } - } else { - t.Fail() - } - } - data, err := ParseFileOrPath(file.Name(), pemType) - failError(t, err) - for i := 0; i < len(data); i++ { - bytes := (data)[i] - certificate := (certs)[i] - ok := assert.Equal(t, bytes, certificate.Raw) - if !ok { - t.Fail() - } - } - - }) - t.Run("Happy flow directory", func(t *testing.T) { - certs, chainPem, _, _, _, err := x509_cert.BuildSelfSignedCertChain("A BIG STRING", "a small one") - failError(t, err) - tempDir, _ := os.MkdirTemp("", "example") - defer func(path string) { - err := os.RemoveAll(path) - if err != nil { - log.Fatal(err) - } - }(tempDir) - for i := 0; i < chainPem.Len(); i++ { - certBlock, ok := chainPem.Get(i) - certAsString := convertToString(certBlock) - file, err := os.CreateTemp(tempDir, "prefix") - failError(t, err) - if ok { - _, err := file.WriteString(certAsString) - failError(t, err) - } else { - t.Fail() - } - } - data, err := ParseFileOrPath(tempDir, pemType) - failError(t, err) - dataMap := make(map[string][]byte) - for i := 0; i < len(data); i++ { - bytes := (data)[i] - hash, err := x509_cert.Hash(bytes, "sha512") - failError(t, err) - dataMap[base64.RawURLEncoding.EncodeToString(hash)] = bytes - } - for i := 0; i < len(certs); i++ { - bytes := (certs)[i].Raw - hash, err := x509_cert.Hash(bytes, "sha512") - failError(t, err) - fileBytes := dataMap[base64.RawURLEncoding.EncodeToString(hash)] - ok := assert.Equal(t, bytes, fileBytes) - if !ok { - t.Fail() - } - } - - }) - -} - -func convertToString(certBlock []byte) string { - certAsString := string(certBlock) - certAsString = strings.ReplaceAll(certAsString, "\\n", "\n") - certAsString = certAsString + "\n" - return certAsString -} - -func failError(t *testing.T, err error) { - if err != nil { - t.Errorf("an error occured: %v", err.Error()) - t.Fatal(err) - } -}