Skip to content

Commit

Permalink
feat: produce NVD meta data for cache (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylong authored Nov 29, 2023
1 parent 348a661 commit 028405f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
}

group 'io.github.jeremylong'
version = '5.0.3'
version = '5.1.0'

repositories {
mavenCentral()
Expand Down
4 changes: 2 additions & 2 deletions open-vulnerability-clients/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ See API usage examples in the [open-vulnerability-store](https://github.com/jere
<dependency>
<groupId>io.github.jeremylong</groupId>
<artifactId>open-vulnerability-clients</artifactId>
<version>5.0.3</version>
<version>5.1.0</version>
</dependency>
```

### gradle

```groovy
implementation 'io.github.jeremylong:open-vulnerability-clients:5.0.3'
implementation 'io.github.jeremylong:open-vulnerability-clients:5.1.0'
```

### api usage
Expand Down
4 changes: 2 additions & 2 deletions vulnz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export JAVA_OPTS="-Xmx2g"
Alternatively, run the CLI using the `-Xmx2g` argument:

```bash
java -Xmx2g -jar ./vulnz-5.0.3.jar
java -Xmx2g -jar ./vulnz-5.1.0.jar
```

### Creating the Cache
Expand All @@ -89,7 +89,7 @@ for file in *.json; do gzip -k "${file}"; done
Alternatively, without using the above install command:

```bash
./vulnz-5.0.3.jar cve --cache --directory ./cache
./vulnz-5.1.0.jar cve --cache --directory ./cache
cd cache
for file in *.json; do gzip -k "${file}"; done
```
Expand Down
1 change: 1 addition & 0 deletions vulnz/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies {
implementation project(':open-vulnerability-store')
implementation 'info.picocli:picocli-spring-boot-starter:4.7.4'
implementation 'com.diogonunes:JColor:5.5.1'
implementation 'commons-io:commons-io:2.15.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.github.jeremylong.vulnz.cli.cache.CacheException;
import io.github.jeremylong.vulnz.cli.cache.CacheProperties;
import io.github.jeremylong.vulnz.cli.model.BasicOutput;
import org.apache.commons.io.output.CountingOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
Expand All @@ -41,9 +42,14 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Year;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -63,6 +69,10 @@ public class CveCommand extends AbstractNvdCommand {
* Reference to the logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(CveCommand.class);
/**
* Hex code characters used in getHex.
*/
private static final String HEXES = "0123456789abcdef";
@CommandLine.ArgGroup(exclusive = true)
ConfigGroup configGroup;

Expand Down Expand Up @@ -213,7 +223,7 @@ public Integer timedCall() throws Exception {
properties.save();
return status;
} catch (CacheException ex) {
LOG.error(ex.getMessage());
LOG.error(ex.getMessage(), ex);
}
return 1;
}
Expand Down Expand Up @@ -274,6 +284,7 @@ private Integer processRequest(NvdCveClientBuilder builder, CacheProperties prop

for (Map.Entry<String, HashMap<String, DefCveItem>> entry : cves.entrySet()) {
File file = new File(properties.getDirectory(), prefix + entry.getKey() + ".json.gz");
File meta = new File(properties.getDirectory(), prefix + entry.getKey() + ".meta");
List<DefCveItem> vulnerabilities = new ArrayList(entry.getValue().values());
vulnerabilities.sort((v1, v2) -> {
return v1.getCve().getId().compareTo(v2.getCve().getId());
Expand All @@ -291,16 +302,62 @@ private Integer processRequest(NvdCveClientBuilder builder, CacheProperties prop
properties.set("lastModifiedDate." + entry.getKey(), timestamp);
CveApiJson20 data = new CveApiJson20(vulnerabilities.size(), 0, vulnerabilities.size(), format, version,
timestamp, vulnerabilities);
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new CacheException("Unable to calculate sha256 checksum", e);
}
long byteCount = 0;
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(fileOutputStream);) {
objectMapper.writeValue(gzipOutputStream, data);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(fileOutputStream);
DigestOutputStream digestOutputStream = new DigestOutputStream(gzipOutputStream, md);
CountingOutputStream countingOutputStream = new CountingOutputStream(digestOutputStream)) {
objectMapper.writeValue(countingOutputStream, data);
byteCount = countingOutputStream.getByteCount();
} catch (IOException ex) {
throw new CacheException("Unable to write cached data: " + file, ex);
}
String checksum = getHex(md.digest());
try (FileOutputStream fileOutputStream = new FileOutputStream(meta);
OutputStreamWriter osw = new OutputStreamWriter(fileOutputStream, "UTF-8");
PrintWriter writer = new PrintWriter(osw)) {
final String lmd = DateTimeFormatter.ISO_DATE_TIME.format(timestamp);
writer.println("lastModifiedDate:" + lmd);
writer.println("size:" + byteCount);
writer.println("gzSize:" + file.length());
writer.println("sha256:" + checksum);
} catch (IOException ex) {
throw new CacheException("Unable to write cached meta-data: " + file, ex);
}
}
return 0;
}

/**
* <p>
* Converts a byte array into a hex string.
* </p>
*
* <p>
* This method was copied from
* <a href="http://www.rgagnon.com/javadetails/java-0596.html">http://www.rgagnon.com/javadetails/java-0596.html</a>
* </p>
*
* @param raw a byte array
* @return the hex representation of the byte array
*/
public static String getHex(byte[] raw) {
if (raw == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
}
return hex.toString();
}

private void collectCves(HashMap<String, HashMap<String, DefCveItem>> cves,
Collection<DefCveItem> vulnerabilities) {
for (DefCveItem item : vulnerabilities) {
Expand Down

0 comments on commit 028405f

Please sign in to comment.