{"id":21538376,"url":"https://github.com/rarimo/ldif-sdk","last_synced_at":"2025-10-18T00:00:22.518Z","repository":{"id":230935637,"uuid":"780411402","full_name":"rarimo/ldif-sdk","owner":"rarimo","description":"Tools for parsing with LDIF files containing PKI certificates","archived":false,"fork":false,"pushed_at":"2025-05-19T12:10:40.000Z","size":7867,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-19T13:31:15.685Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rarimo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-04-01T12:29:19.000Z","updated_at":"2025-05-19T12:10:18.000Z","dependencies_parsed_at":"2025-05-19T13:40:05.386Z","dependency_job_id":null,"html_url":"https://github.com/rarimo/ldif-sdk","commit_stats":null,"previous_names":["rarimo/ldif-sdk"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/rarimo/ldif-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rarimo%2Fldif-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rarimo%2Fldif-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rarimo%2Fldif-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rarimo%2Fldif-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rarimo","download_url":"https://codeload.github.com/rarimo/ldif-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rarimo%2Fldif-sdk/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261480142,"owners_count":23164849,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T04:11:47.604Z","updated_at":"2025-10-18T00:00:17.449Z","avatar_url":"https://github.com/rarimo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LDIF SDK\n## Description\n\nGeneral toolkit to work with ICAO CSCA MasterLists. It may:\n * Read and parse into different data structures `.ldif` files (as an example [ICAO PKD](https://pkddownloadsg.icao.int/) was used)\n * Create dynamic Merkle tree with treap data structure\n * Hash underlying certificates public keys\n * Build Merkle tree from previous point that stores certificates' hashes and verifies inclusion of a certificate \n\nMoreover, this library is compatible with [gomobile](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile) (no C libraries and only compatible types). \nBut to be able to surely compile it high-level [wrapper](./mt/main.go) should be used, binding scripts could be found \nin the [scripts](./scripts) directory.\n \n## LDIF certificates parser\n\nAn LDIF file consists of a series of records separated by line separators.  A\nrecord consists of a sequence of lines describing a directory entry,\nor a sequence of lines describing a set of changes to a directory\nentry. More info about LDIF format may be found in [RFC 2849](https://datatracker.ietf.org/doc/html/rfc2849).\n\nOur library provides different approaches for parsing data: reading file from \nfilesystem, reading data from `io.Reader` or from raw file bytes. Moreover, there is an ability to parse file that is \nstored in S3 compatible _public_ file storage. Under the hood it looks through the file,\nsearching by desired phrases, then fetched parts (master lists) decoded and unmarshalled to the structure with \nunderlying certificates list.\n\nTo start working with ICAO ldif parser these code snippets may be used:\n\n```go\n    converter, err := FromFile(pathToLdifFile) // Read file and parse it\n    if err != nil {\n        return errors.Wrap(err, \"failed to create new ldif converter\")\t\n    }\n\t\n    ...\n\n    converter, err := FromReader(reader) // Read data from io.Reader and parse it\n    if err != nil {\n        return errors.Wrap(err, \"failed to create new ldif converter\")\n    }\n\t\n\t...\n\t\n    converter, err := FromS3Bucket(context.Background(), bucket, file) // Read data from remote file storage \n    if err != nil {\n    return errors.Wrap(err, \"failed to create new ldif converter\")\n    }\n\t\n    ...\n\n    converter, err := NewLDIF(rawBytes) // Parse raw file bytes \n    if err != nil {\n        return errors.Wrap(err, \"failed to create new ldif converter\")\n    }\n```\n\nAfter reading and parsing LDIF data these certificates can be converted into different formats: \n\n* PEM - using `converter.ToPem()` will reproduce an array of strings that stores certificates in a [PEM](https://datatracker.ietf.org/doc/html/rfc7468) format\n* X509 - using `converter.ToX509()` witll return an array of certificates in a [x509](https://datatracker.ietf.org/doc/html/rfc5280) format \n\nIn addition, there is a method `converter.RawPubKeys()` that gives an ability to get all public keys from parsed certificates, except duplicates and unsupported types (\nnowadays it handles only RSA public keys).\n\nMore examples and usages can be found in [test file](./ldif/ldif_test.go). \n\n\n## Merkle Tree\n\n### Treap Merkle Tree\nDynamic treap-based Merkle tree is used to store the CSCA public key hashes, see [treap](https://en.wikipedia.org/wiki/Treap).\n\nTo start working with tree `New()` should be called, the realisation implements basic interface to work with tree that looks like:\n\n```go\n    type ITreap interface {\n        Remove(key []byte)\n        Insert(key []byte, priority uint64)\n        MerklePath(key []byte) ([][]byte, []int)\n        MerkleRoot() []byte\n    }\n```\n\nWorth to notice, if the tree has to be equal on different services with the same input keys, the priority should be\ngenerated deterministically, otherwise the leaf order will be different. This package also provides some [tests](./mt/treap_tree_test.go)\nthat can be used as an example.\n\n## Cert Tree\n\nFurthermore, there is an interface that builds Treap Merkle Tree from certificates list. This wrapper was created\nin accordance with the requirements for mobile developers, so the function arguments and responses consist of simple\ntypes. \n\nAs was mentioned before, the priority for our keys are generated deterministically using such formula: \n`priority = hash(key) mod MAX_UINT64`.\n\nThis package provides several options to build certificates tree from:\n* encoded x509 certificates list - `BuildTree(encodedList)` - this function will decode the argument, retrieve public\nkeys from the certificates and build a new tree;\n* raw leaves (public keys) - `BuildFromRaw(leaves)` - this function will hash raw keys and then build tree;\n* Cosmos network - `BuildFromCosmos(grpcAddr, isSecure)` - this function will establish gRPC connection for given\naddress and fetch tree that is stored in Cosmos network using `/rarimo/rarimo-core/cscalist/tree` query. Then it\nwill build tree with given key hashes.\n\nPrevious functions returns new instance of a certificate tree that has several useful method to work with created data \nstructure:\n* `Root()` - get current tree root\n* `IsExists()` - check if the underlying treap tree is initialised (or whether the root is empty) \n* `GenerateInclusionProof(pemCertificate)` - generates inclusion proof for given certificate. The proof is such structure:\n```go\n    type Proof struct {\n        // Siblings is a list of non-empty sibling hashes to recover root.\n        Siblings [][]byte `json:\"siblings\"`\n    }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frarimo%2Fldif-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frarimo%2Fldif-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frarimo%2Fldif-sdk/lists"}