1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.analyzer;
19
20 import org.apache.commons.io.FileUtils;
21 import org.owasp.dependencycheck.Engine;
22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
23 import org.owasp.dependencycheck.dependency.Confidence;
24 import org.owasp.dependencycheck.dependency.Dependency;
25 import org.owasp.dependencycheck.utils.FileFilterBuilder;
26 import org.owasp.dependencycheck.utils.Settings;
27
28 import java.io.File;
29 import java.io.FileFilter;
30 import java.io.IOException;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
40
41 private static final int HEXADECIMAL = 16;
42
43
44
45 private static final String OPENSSLV_H = "opensslv.h";
46
47
48
49
50 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
51 private static final Pattern VERSION_PATTERN = Pattern.compile(
52 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL
53 | Pattern.CASE_INSENSITIVE);
54 private static final int MAJOR_OFFSET = 28;
55 private static final long MINOR_MASK = 0x0ff00000L;
56 private static final int MINOR_OFFSET = 20;
57 private static final long FIX_MASK = 0x000ff000L;
58 private static final int FIX_OFFSET = 12;
59 private static final long PATCH_MASK = 0x00000ff0L;
60 private static final int PATCH_OFFSET = 4;
61 private static final int NUM_LETTERS = 26;
62 private static final int STATUS_MASK = 0x0000000f;
63
64
65
66
67
68
69
70 static String getOpenSSLVersion(long openSSLVersionConstant) {
71 final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
72 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
73 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
74 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
75 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
76 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
77 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
78 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
79 }
80
81
82
83
84
85
86 @Override
87 public String getName() {
88 return "OpenSSL Source Analyzer";
89 }
90
91
92
93
94
95
96 @Override
97 public AnalysisPhase getAnalysisPhase() {
98 return AnalysisPhase.INFORMATION_COLLECTION;
99 }
100
101
102
103
104
105
106 @Override
107 protected FileFilter getFileFilter() {
108 return OPENSSLV_FILTER;
109 }
110
111
112
113
114
115
116 @Override
117 protected void initializeFileTypeAnalyzer() throws Exception {
118
119 }
120
121
122
123
124
125
126
127
128 @Override
129 protected void analyzeFileType(Dependency dependency, Engine engine)
130 throws AnalysisException {
131 final File file = dependency.getActualFile();
132 final String parentName = file.getParentFile().getName();
133 boolean found = false;
134 final String contents = getFileContents(file);
135 if (!contents.isEmpty()) {
136 final Matcher matcher = VERSION_PATTERN.matcher(contents);
137 if (matcher.find()) {
138 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
139 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
140 found = true;
141 }
142 }
143 if (found) {
144 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
145 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
146 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
147 } else {
148 engine.getDependencies().remove(dependency);
149 }
150 }
151
152
153
154
155
156
157
158
159 private String getFileContents(final File actualFile)
160 throws AnalysisException {
161 String contents;
162 try {
163 contents = FileUtils.readFileToString(actualFile).trim();
164 } catch (IOException e) {
165 throw new AnalysisException(
166 "Problem occurred while reading dependency file.", e);
167 }
168 return contents;
169 }
170
171 @Override
172 protected String getAnalyzerEnabledSettingKey() {
173 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
174 }
175 }