Coverage Report - org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler
 
Classes in this File Line Coverage Branch Coverage Complexity
NvdCve12Handler
94%
50/53
82%
28/34
2.8
NvdCve12Handler$Element
77%
7/9
N/A
2.8
 
 1  
 /*
 2  
  * This file is part of dependency-check-core.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  *
 16  
  * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
 17  
  */
 18  
 package org.owasp.dependencycheck.data.update.nvd;
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.HashMap;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 import org.owasp.dependencycheck.dependency.VulnerableSoftware;
 25  
 import org.xml.sax.Attributes;
 26  
 import org.xml.sax.SAXException;
 27  
 import org.xml.sax.SAXNotSupportedException;
 28  
 import org.xml.sax.helpers.DefaultHandler;
 29  
 
 30  
 /**
 31  
  * A SAX Handler that will parse the NVD CVE XML (schema version 1.2). This parses the xml and retrieves a listing of
 32  
  * CPEs that have previous versions specified. The previous version information is not in the 2.0 version of the schema
 33  
  * and is useful to ensure accurate identification (or at least complete).
 34  
  *
 35  
  * @author Jeremy Long
 36  
  */
 37  1
 public class NvdCve12Handler extends DefaultHandler {
 38  
 
 39  
     /**
 40  
      * the supported schema version.
 41  
      */
 42  
     private static final String CURRENT_SCHEMA_VERSION = "1.2";
 43  
     /**
 44  
      * the current vulnerability.
 45  
      */
 46  
     private String vulnerability;
 47  
     /**
 48  
      * a list of vulnerable software.
 49  
      */
 50  
     private List<VulnerableSoftware> software;
 51  
     /**
 52  
      * the vendor name.
 53  
      */
 54  
     private String vendor;
 55  
     /**
 56  
      * the product name.
 57  
      */
 58  
     private String product;
 59  
     /**
 60  
      * if the nvd cve should be skipped because it was rejected.
 61  
      */
 62  1
     private boolean skip = false;
 63  
     /**
 64  
      * flag indicating if there is a previous version.
 65  
      */
 66  1
     private boolean hasPreviousVersion = false;
 67  
     /**
 68  
      * The current element.
 69  
      */
 70  1
     private final Element current = new Element();
 71  
     /**
 72  
      * a map of vulnerabilities.
 73  
      */
 74  
     private Map<String, List<VulnerableSoftware>> vulnerabilities;
 75  
 
 76  
     /**
 77  
      * Get the value of vulnerabilities.
 78  
      *
 79  
      * @return the value of vulnerabilities
 80  
      */
 81  
     public Map<String, List<VulnerableSoftware>> getVulnerabilities() {
 82  1
         return vulnerabilities;
 83  
     }
 84  
 
 85  
     @Override
 86  
     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
 87  1222
         current.setNode(qName);
 88  1222
         if (current.isEntryNode()) {
 89  27
             vendor = null;
 90  27
             product = null;
 91  27
             hasPreviousVersion = false;
 92  27
             final String reject = attributes.getValue("reject");
 93  27
             skip = "1".equals(reject);
 94  27
             if (!skip) {
 95  26
                 vulnerability = attributes.getValue("name");
 96  26
                 software = new ArrayList<VulnerableSoftware>();
 97  
             } else {
 98  1
                 vulnerability = null;
 99  1
                 software = null;
 100  
             }
 101  27
         } else if (!skip && current.isProdNode()) {
 102  52
             vendor = attributes.getValue("vendor");
 103  52
             product = attributes.getValue("name");
 104  1143
         } else if (!skip && current.isVersNode()) {
 105  761
             final String prev = attributes.getValue("prev");
 106  761
             if (prev != null && "1".equals(prev)) {
 107  1
                 hasPreviousVersion = true;
 108  1
                 final String edition = attributes.getValue("edition");
 109  1
                 final String num = attributes.getValue("num");
 110  
 
 111  
                 /*yes yes, this may not actually be an "a" - it could be an OS, etc. but for our
 112  
                  purposes this is good enough as we won't use this if we don't find a corresponding "a"
 113  
                  in the nvd cve 2.0. */
 114  1
                 final int cpeLen = 8 + vendor.length() + product.length()
 115  1
                     + (null != num ? (1 + num.length()) : 0)
 116  0
                     + (null != edition ? (1 + edition.length()) : 0);
 117  1
                 final StringBuilder cpe = new StringBuilder(cpeLen);
 118  1
                 cpe.append("cpe:/a:").append(vendor).append(':').append(product);
 119  1
                 if (num != null) {
 120  1
                     cpe.append(':').append(num);
 121  
                 }
 122  1
                 if (edition != null) {
 123  0
                     cpe.append(':').append(edition);
 124  
                 }
 125  1
                 final VulnerableSoftware vs = new VulnerableSoftware();
 126  1
                 vs.setCpe(cpe.toString());
 127  1
                 vs.setPreviousVersion(prev);
 128  1
                 software.add(vs);
 129  
             }
 130  761
         } else if (current.isNVDNode()) {
 131  1
             final String nvdVer = attributes.getValue("nvd_xml_version");
 132  1
             if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
 133  0
                 throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
 134  
             }
 135  1
             vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
 136  
         }
 137  1222
     }
 138  
 
 139  
     @Override
 140  
     public void endElement(String uri, String localName, String qName) throws SAXException {
 141  1222
         current.setNode(qName);
 142  1222
         if (current.isEntryNode()) {
 143  27
             if (!skip && hasPreviousVersion) {
 144  1
                 vulnerabilities.put(vulnerability, software);
 145  
             }
 146  27
             vulnerability = null;
 147  27
             software = null;
 148  
         }
 149  1222
     }
 150  
 
 151  
     // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
 152  
     /**
 153  
      * A simple class to maintain information about the current element while parsing the NVD CVE XML.
 154  
      */
 155  1
     protected static class Element {
 156  
 
 157  
         /**
 158  
          * A node type in the NVD CVE Schema 1.2.
 159  
          */
 160  
         public static final String NVD = "nvd";
 161  
         /**
 162  
          * A node type in the NVD CVE Schema 1.2.
 163  
          */
 164  
         public static final String ENTRY = "entry";
 165  
         /**
 166  
          * A node type in the NVD CVE Schema 1.2.
 167  
          */
 168  
         public static final String VULN_SOFTWARE = "vuln_soft";
 169  
         /**
 170  
          * A node type in the NVD CVE Schema 1.2.
 171  
          */
 172  
         public static final String PROD = "prod";
 173  
         /**
 174  
          * A node type in the NVD CVE Schema 1.2.
 175  
          */
 176  
         public static final String VERS = "vers";
 177  
         /**
 178  
          * The name of the current node.
 179  
          */
 180  
         private String node;
 181  
 
 182  
         /**
 183  
          * Gets the value of node.
 184  
          *
 185  
          * @return the value of node
 186  
          */
 187  
         public String getNode() {
 188  0
             return this.node;
 189  
         }
 190  
 
 191  
         /**
 192  
          * Sets the value of node.
 193  
          *
 194  
          * @param node new value of node
 195  
          */
 196  
         public void setNode(String node) {
 197  2444
             this.node = node;
 198  2444
         }
 199  
 
 200  
         /**
 201  
          * Checks if the handler is at the NVD node.
 202  
          *
 203  
          * @return true or false
 204  
          */
 205  
         public boolean isNVDNode() {
 206  382
             return NVD.equals(node);
 207  
         }
 208  
 
 209  
         /**
 210  
          * Checks if the handler is at the ENTRY node.
 211  
          *
 212  
          * @return true or false
 213  
          */
 214  
         public boolean isEntryNode() {
 215  2444
             return ENTRY.equals(node);
 216  
         }
 217  
 
 218  
         /**
 219  
          * Checks if the handler is at the VULN_SOFTWARE node.
 220  
          *
 221  
          * @return true or false
 222  
          */
 223  
         public boolean isVulnSoftwareNode() {
 224  0
             return VULN_SOFTWARE.equals(node);
 225  
         }
 226  
 
 227  
         /**
 228  
          * Checks if the handler is at the PROD node.
 229  
          *
 230  
          * @return true or false
 231  
          */
 232  
         public boolean isProdNode() {
 233  1192
             return PROD.equals(node);
 234  
         }
 235  
 
 236  
         /**
 237  
          * Checks if the handler is at the VERS node.
 238  
          *
 239  
          * @return true or false
 240  
          */
 241  
         public boolean isVersNode() {
 242  1140
             return VERS.equals(node);
 243  
         }
 244  
     }
 245  
     // </editor-fold>
 246  
 }