Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: produce NVD meta data for cache #100

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading