Skip to content

flexca/eNot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

146 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eNot — Encoding Notations

Build Maven Central License Java

eNot is a Java templating engine that transforms JSON/YAML structures into binary-encoded data (ASN.1 DER, BER-TLV, and more). By separating structure from values, eNot eliminates the fragility of hand-written encoding and provides a robust, maintainable way to generate complex binary payloads.

Quick Start

1. Add dependency

Add the following dependency to your pom.xml:

<dependency>
    <groupId>io.github.flexca</groupId>
    <artifactId>enot-core</artifactId>
    <version>1.0.0</version>
</dependency>

Or to build.gradle:

implementation 'io.github.flexca:enot-core:1.0.0'

2. Create a template

eNot templates mirror your data structure. For example, to encode this ASN.1 definition:

ExampleStructure ::= SET {
    data  SEQUENCE {
        oid   OBJECT IDENTIFIER,
        name  UTF8String
    }
}

You define the following template.yaml:

type: asn.1
attributes: { tag: set }
body:
  type: asn.1
  attributes: { tag: sequence }
  body:
    - type: asn.1
      attributes: { tag: object_identifier }
      body: "${my_oid}"
    - type: asn.1
      attributes: { tag: utf8_string }
      body: "${my_text}"

Check out the eNot reference for a deep dive into elements and scoping.

3. Encode your data

Supply runtime values via SerializationContext to generate the binary output:

import io.github.flexca.enot.core.exception.EnotException;
import io.github.flexca.enot.core.registry.EnotRegistry;
import io.github.flexca.enot.core.serializer.context.SerializationContext;
import io.github.flexca.enot.core.types.asn1.Asn1TypeSpecification;
import io.github.flexca.enot.core.types.system.SystemTypeSpecification;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.dataformat.yaml.YAMLFactory;

import java.util.Base64;
import java.util.List;

public class EnotQuickStart {

    // YAML template:
    private static final String ENOT_TEMPLATE = """
            type: asn.1
            attributes: { tag: set }
            body:
              type: asn.1
              attributes: { tag: sequence }
              body:
                - type: asn.1
                  attributes: { tag: object_identifier }
                  body: "${my_oid}"
                - type: asn.1
                  attributes: { tag: utf8_string }
                  body: "${my_text}"
            """;

    public static void main(String[] args) {

        // Jackson object mappers:
        ObjectMapper jsonObjectMapper = new ObjectMapper();                     // Required if you are using JSON
        ObjectMapper yamlObjectMapper = new ObjectMapper(new YAMLFactory());    // Required if you are using YAML

        // Registry allow to supply eNot type specification:
        EnotRegistry registry = new EnotRegistry.Builder()
                .withTypeSpecification(new SystemTypeSpecification())    // System elements - loops, conditions and other utilites
                .withTypeSpecification(new Asn1TypeSpecification())      // ASN.1 elements - require to serialize to ASN.1 DER
                .build();

        // Enot - facade for parsing, serialization, etc:
        Enot enot = new Enot.Builder()
                .withRegistry(registry)                    // Adding registry
                .withJsonObjectMapper(jsonObjectMapper)    // Add JSON ObjectMapper if you are using JSON templates
                .withYamlObjectMapper(yamlObjectMapper)    // Add YAML ObjectMapper if you are using YAML templates
                .build();

        // Serialization context - hold params to replace placeholders:
        SerializationContext serializationContext = new SerializationContext.Builder()
                .withParam("my_oid", "1.2.840.113549.1.1.1")    // Value to replace ${my_oid} placeholder in template
                .withParam("my_text", "eNot")                   // Value to replace ${my_text} placeholder in template
                .build();

        try {
            // Serializing template with params to binary:
            List<byte[]> result = enot.serialize(ENOT_TEMPLATE, serializationContext);
            // Encoding result to Base64:
            String resultBase64Encoded = Base64.getEncoder().encodeToString(result.get(0));
            // Printing Base64 encoded result:
            System.out.println("Result: " + resultBase64Encoded);
        } catch (EnotException e) {
            e.printStackTrace();
        }
    }
}

Key Features

  • Human-readable templates — eNot templates are plain JSON or YAML files that mirror the binary structure they produce. They are easy to read, review, and version-control. Because templates are data, not code, they can be updated and reloaded at runtime without rebuilding the application. See eNot format reference.

  • ASN.1 DER encoding — Full support for DER-encoded ASN.1 structures: sequences, sets, OIDs, strings, integers, time types, context tagging, and more. See ASN.1 elements.

  • BER-TLV support — BER-TLV encoding is available as a plug-in module, demonstrating that the engine is not tied to ASN.1. See ber-tlv module.

  • Control logicloop and condition system elements make templates truly flexible: iterate over parameter lists, include elements conditionally, and handle variable-length structures without any code changes.

  • Composition — Break large templates into smaller, named pieces and reuse them with the reference system element. Build complex structures from tested, independently maintained parts.

  • Extensibility — The type system is open: register your own element types alongside the built-in ones. See Adding a new eNot element type.

  • Interactive web tool — Try eNot instantly in the browser without writing any Java. The web tool ships as a Docker image with a side-by-side template/params editor, YAML/JSON switching, and one-click example generation. See web-tool.

  • Detailed documentation — Every element type, attribute, and constraint is documented with examples. See Documentation.

Note

eNot is designed for small, structured payloads — certificate fields, extensions, smart-card commands, and similar structures that are kilobytes in size. The engine holds the entire structure in memory during serialization. It is not suitable for large binary payloads (hundreds of megabytes), and using it for such workloads — especially under concurrent load — may cause out-of-memory errors.


Modules

Module Artifact Description
core enot-core Parser, serializer, expression engine, type registry, and all built-in element types (ASN.1 DER + system elements). The only dependency needed for most use cases.
ber-tlv enot-ber-tlv BER-TLV encoding support. A plug-in module that demonstrates the extensible type system beyond ASN.1.
web-tool Browser-based interactive playground for evaluating eNot templates. Not a library dependency — run it via Docker or as a standalone JAR.

Contributing

Issues and pull requests are welcome. If you find a bug, have a feature request, or want to add support for a new encoding format, please open an issue on GitHub.


Acknowledgements

eNot is built on top of several excellent open-source libraries:


License

Apache License 2.0 — see LICENSE.

About

eNot (Encoding Notations) is a YAML or JSON based templating engine that serializes structured data into binary formats such as ASN.1 or BER-TLV

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors