Skip to content

Java library for generating, consuming, and operating on OpenVEX documents

License

Notifications You must be signed in to change notification settings

p-ssanders/jvex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

License build maven-central javadoc

jvex

Java library for generating, consuming, and operating on VEX documents based on the OpenVEX Specification v0.2.0

Installing

Maven

<dependency>
  <groupId>dev.samsanders.openvex</groupId>
  <artifactId>jvex</artifactId>
  <version>0.1.0</version>
</dependency>

Gradle

implementation 'dev.samsanders.openvex:jvex:0.1.0'

Usage

Create a VEX Document

This example creates a Document using the public constructor.

Document document = new Document("Spring Builds <spring-builds@users.noreply.github.com>");
document.setRole("Project Release Bot");

Product product = new Product(URI.create("pkg:oci/git@sha256:23a264e6e429852221a963e9f17338ba3f5796dc7086e46439a6f4482cf6e0cb"));
product.setIdentifiers(new Identifiers(new PackageURL("pkg:oci/git@sha256:23a264e6e429852221a963e9f17338ba3f5796dc7086e46439a6f4482cf6e0cb")));

Hashes hashes = new Hashes();
hashes.setSha256("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
product.setHashes(hashes);

Vulnerability vulnerability = new Vulnerability("CVE-2021-44228");
vulnerability.setId(URI.create("https://nvd.nist.gov/vuln/detail/CVE-2021-44228"));
vulnerability.setDescription("Remote code injection in Log4j");
vulnerability.setAliases(Collections.singletonList("GHSA-jfh8-c2jp-5v3q"));

Statement statement = new Statement(Collections.singletonList(product), vulnerability, Status.not_affected);
statement.setJustification(Justification.vulnerable_code_not_in_execute_path);
statement.setImpactStatement("Spring Boot users are only affected by this vulnerability if they have switched the " +
        "default logging system to Log4J2. The log4j-to-slf4j and log4j-api jars that we include in spring-boot-starter-logging " +
        "cannot be exploited on their own. Only applications using log4j-core and including user input in log messages are vulnerable.");
document.getStatements().add(statement);

The document can be serialized to JSON using the toJson convenience method that delegates to a pre-configured jackson-databind ObjectMapper, or you can use your own ObjectMapper. Additionally, any framework that uses jackson-databind, (e.g.: Spring Web MVC) can be used to serialize a Document.

The serialization process includes validation to only produce valid OpenVEX 0.2.0 JSON.

The Document above will serialize to the following JSON:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://openvex.dev/docs/public/vex-7b79113df873170fddc9def6166d7e7c8ba4d8ad09fb164005c41cf82d8b6068",
  "author": "Spring Builds <spring-builds@users.noreply.github.com>",
  "role": "Project Release Bot",
  "timestamp": "2023-09-28T10:45:44.884207-06:00",
  "version": 1,
  "tooling": "jvex/0.1.0",
  "statements": [
    {
      "products": [
        {
          "@id": "pkg:oci/git@sha256:23a264e6e429852221a963e9f17338ba3f5796dc7086e46439a6f4482cf6e0cb",
          "identifiers": {
            "purl": "pkg:oci/git@sha256%3A23a264e6e429852221a963e9f17338ba3f5796dc7086e46439a6f4482cf6e0cb"
          },
          "hashes": {
            "sha-256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
          }
        }
      ],
      "vulnerability": {
        "name": "CVE-2021-44228",
        "description": "Remote code injection in Log4j",
        "aliases": [
          "GHSA-jfh8-c2jp-5v3q"
        ],
        "@id": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228"
      },
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path",
      "impact_statement": "Spring Boot users are only affected by this vulnerability if they have switched the default logging system to Log4J2. The log4j-to-slf4j and log4j-api jars that we include in spring-boot-starter-logging cannot be exploited on their own. Only applications using log4j-core and including user input in log messages are vulnerable."
    }
  ]
}

Note the defaults:

  • @context defaults to https://openvex.dev/ns/v0.2.0
  • @id is generated based on the "canonical hash" algorithm
  • timestamp defaults to now
  • version defaults to 1
  • tooling defaults to "jvex/0.1.0"
Consume a VEX Document

Deserialize JSON using jackson-databind or a framework that uses it (e.g.: Spring Web MVC). The deserialization process includes validation to only accept valid OpenVEX 0.2.0 JSON. It fails if the JSON is invalid according to the spec (i.e.: MUSTs, required fields, types, conditional logic, etc.)

Document from(InputStream inputStream) throws IOException {
    ObjectReader reader = new ObjectMapper().registerModule(new JavaTimeModule()).reader();
    return reader.readValue(inputStream, Document.class);
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Document document) {
    // ...
}
Add a Statement to a Document

A statement is added to a Document by invoking getStatements().add() on the Document instance.

Adding a statement to a new instance has no side effects, the statement is added to the document without a timestamp and therefore inherits the document's timestamp.

Adding a statement to deserialized instances has side effects to implement OpenVEX 0.2.0 "Updating Statements with Inherited Data" use-case.