1 /** 2 * Portions of this software was developed by employees of the National Institute 3 * of Standards and Technology (NIST), an agency of the Federal Government and is 4 * being made available as a public service. Pursuant to title 17 United States 5 * Code Section 105, works of NIST employees are not subject to copyright 6 * protection in the United States. This software may be subject to foreign 7 * copyright. Permission in the United States and in foreign countries, to the 8 * extent that NIST may hold copyright, to use, copy, modify, create derivative 9 * works, and distribute this software and its documentation without fee is hereby 10 * granted on a non-exclusive basis, provided that this notice and disclaimer 11 * of warranty appears in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 14 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 15 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 17 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 18 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 19 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 20 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 21 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 22 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 23 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 24 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 25 */ 26 27 package gov.nist.secauto.swid.builder.resource.firmware; 28 29 import gov.nist.secauto.swid.builder.AbstractBuilder; 30 import gov.nist.secauto.swid.builder.ValidationException; 31 import gov.nist.secauto.swid.builder.resource.HashAlgorithm; 32 import gov.nist.secauto.swid.builder.resource.HashUtils; 33 import gov.nist.secauto.swid.builder.util.Util; 34 35 import java.io.BufferedInputStream; 36 import java.io.File; 37 import java.io.FileInputStream; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.math.BigInteger; 41 import java.security.NoSuchAlgorithmException; 42 import java.util.LinkedList; 43 import java.util.List; 44 import java.util.Objects; 45 46 public class FirmwarePayloadBuilder extends AbstractBuilder { 47 48 private FirmwareIdentifier id; 49 private String packageIdentifier; 50 private String description; 51 private Integer formatType; 52 private byte[] formatGuidance; 53 private BigInteger size; 54 private BigInteger simpleVersion; 55 // private FirmwarePayloadVersion version; 56 private List<FirmwarePayloadDigest> digests = new LinkedList<>(); 57 private String componentIndex; 58 private FirmwareIdentifier storageId; 59 private List<FirmwareRequirement<FirmwareCondition>> conditions = new LinkedList<>(); 60 private List<FirmwareRequirement<FirmwareDirective>> directives = new LinkedList<>(); 61 // private VersionedDependency targetDependency; 62 // private MinimalVersion targetMinimalVersion; 63 // private List<FirmwarePayloadRelationship> relationships; 64 private FirmwarePayloadPackage firmwarePackage; 65 66 /** 67 * Retrieve the identifier of the firmware payload. 68 * 69 * @return the id 70 */ 71 public FirmwareIdentifier getId() { 72 return id; 73 } 74 75 /** 76 * Set the id of the firmware payload. 77 * 78 * @param id 79 * the firmware's identifier 80 * @return the same builder instance 81 */ 82 public FirmwarePayloadBuilder id(FirmwareIdentifier id) { 83 Objects.requireNonNull(id, "id"); 84 this.id = id; 85 return this; 86 } 87 88 /** 89 * Retrieve the package identifier of the firmware manifest. 90 * 91 * @return the packageIdentifier 92 */ 93 public String getPackageIdentifier() { 94 return packageIdentifier; 95 } 96 97 /** 98 * Set the package identifier. 99 * 100 * @param packageIdentifier 101 * a {@code non-null} package identifier 102 * @return the same builder instance 103 */ 104 public FirmwarePayloadBuilder packageIdentifier(String packageIdentifier) { 105 Util.requireNonEmpty(packageIdentifier, "packageIdentifier"); 106 this.packageIdentifier = packageIdentifier; 107 return this; 108 } 109 110 /** 111 * Retrieve the description of the firmware payload. 112 * 113 * @return the description 114 */ 115 public String getDescription() { 116 return description; 117 } 118 119 /** 120 * Set the version of the firmware payload. 121 * 122 * @param description 123 * the firmware's description 124 * @return the same builder instance 125 */ 126 public FirmwarePayloadBuilder description(String description) { 127 Util.requireNonEmpty(description, "description"); 128 this.description = description; 129 return this; 130 } 131 132 /** 133 * Retrieve the format type of the firmware payload. 134 * 135 * @return the type 136 */ 137 public int getFormatType() { 138 return formatType; 139 } 140 141 /** 142 * Set the format type. 143 * 144 * @param type 145 * a format type 146 * @return the same builder instance 147 */ 148 public FirmwarePayloadBuilder formatType(int type) { 149 this.formatType = type; 150 return this; 151 } 152 153 /** 154 * Retrieve the firmware payload's format guidance. 155 * 156 * @return the format guidance 157 */ 158 public byte[] getFormatGuidance() { 159 return formatGuidance; 160 } 161 162 /** 163 * Set the firmware payload's format guidance. 164 * 165 * @param bytes 166 * guidance a {@code non-null} byte string 167 * @return the same builder instance 168 */ 169 public FirmwarePayloadBuilder formatGuidance(byte[] bytes) { 170 Objects.requireNonNull(bytes, "bytes"); 171 this.formatGuidance = bytes; 172 return this; 173 } 174 175 /** 176 * Retrieve the size the firmware payload. 177 * 178 * @return the size 179 */ 180 public BigInteger getSize() { 181 return size; 182 } 183 184 /** 185 * Set the size. 186 * 187 * @param size 188 * a {@code non-null} size 189 * @return the same builder instance 190 */ 191 public FirmwarePayloadBuilder size(BigInteger size) { 192 Objects.requireNonNull(size, "size"); 193 this.size = size; 194 return this; 195 } 196 197 /** 198 * Retrieve the simple version of the firmware payload. 199 * 200 * @return the version 201 */ 202 public BigInteger getSimpleVersion() { 203 return simpleVersion; 204 } 205 206 // /** 207 // * Set the version of the payload. 208 // * 209 // * @param version 210 // * a {@code non-null} version 211 // * @return the same builder instance 212 // */ 213 // public FirmwarePayloadBuilder version(FirmwarePayloadVersion version) { 214 // Objects.requireNonNull(version, "version"); 215 // this.version = version; 216 // return this; 217 // } 218 // 219 // /** 220 // * Retrieve the simple version of the firmware payload. 221 // * 222 // * @return the version 223 // */ 224 // public FirmwarePayloadVersion getVersion() { 225 // return version; 226 // } 227 228 /** 229 * Set the simple version of the payload. 230 * 231 * @param version 232 * a {@code non-null} version 233 * @return the same builder instance 234 */ 235 public FirmwarePayloadBuilder simpleVersion(BigInteger version) { 236 Objects.requireNonNull(version, "version"); 237 this.simpleVersion = version; 238 return this; 239 } 240 241 /** 242 * Retrieve the digests of the firmware payload. 243 * 244 * @return the digests 245 */ 246 public List<FirmwarePayloadDigest> getDigests() { 247 return digests; 248 } 249 250 /** 251 * Adds a new digest to the list of digests. 252 * 253 * @param digest 254 * the digest to add 255 * @return the same builder instance 256 */ 257 public FirmwarePayloadBuilder addDigest(FirmwarePayloadDigest digest) { 258 Objects.requireNonNull(digest, "digest"); 259 this.digests.add(digest); 260 return this; 261 } 262 263 /** 264 * Sets the to-be-built file's hash value, for the provided algorithm, to the provided value. An 265 * {@link InputStream} is used to retrieve the files contents to calculate the hash value. The 266 * caller is responsible for closing the stream used by this method. 267 * 268 * @param type 269 * the type of resource this digest is for 270 * @param algorithm 271 * the algorithm to establish a hash value for 272 * @param file 273 * the file to hash 274 * @return the same builder instance 275 * @throws NoSuchAlgorithmException 276 * if the hash algorithm is not supported 277 * @throws IOException 278 * if an error occurs while reading the stream 279 */ 280 public FirmwarePayloadBuilder addDigest(DigestType type, HashAlgorithm algorithm, File file) 281 throws NoSuchAlgorithmException, IOException { 282 try (InputStream is = new BufferedInputStream(new FileInputStream(file))) { 283 return addDigest(type, algorithm, is); 284 } 285 } 286 287 /** 288 * Sets the file's hash value, for the provided algorithm, to the provided value. An 289 * {@link InputStream} is used to retrieve the files contents to calculate the hash value. The 290 * caller is responsible for closing the stream used by this method. 291 * 292 * @param type 293 * the type of resource this digest is for 294 * @param algorithm 295 * the algorithm to establish a hash value for 296 * @param is 297 * an {@link InputStream} that can be used to read the file 298 * @return the same builder instance 299 * @throws NoSuchAlgorithmException 300 * if the hash algorithm is not supported 301 * @throws IOException 302 * if an error occurs while reading the stream 303 */ 304 public FirmwarePayloadBuilder addDigest(DigestType type, HashAlgorithm algorithm, InputStream is) 305 throws NoSuchAlgorithmException, IOException { 306 byte[] digest = HashUtils.hash(algorithm, is); 307 return addDigest(type, algorithm, digest); 308 } 309 310 /** 311 * Sets the file's hash value, for the provided algorithm, to the provided value. 312 * 313 * @param type 314 * the type of resource this digest is for 315 * @param algorithm 316 * the algorithm to establish a hash value for 317 * @param digest 318 * an array of bytes representing the digest value 319 * @return the same builder instance 320 */ 321 public FirmwarePayloadBuilder addDigest(DigestType type, HashAlgorithm algorithm, byte[] digest) { 322 Objects.requireNonNull(type, "type"); 323 Objects.requireNonNull(algorithm, "algorithm"); 324 Objects.requireNonNull(digest, "digest"); 325 326 FirmwarePayloadDigestrmware/FirmwarePayloadDigest.html#FirmwarePayloadDigest">FirmwarePayloadDigest payloadDigest = new FirmwarePayloadDigest(type, algorithm, digest); 327 return addDigest(payloadDigest); 328 } 329 330 /** 331 * Retrieve the index value of the firmware component. 332 * 333 * @return the componentIndex 334 */ 335 public String getComponentIndex() { 336 return componentIndex; 337 } 338 339 /** 340 * Set the component index. 341 * 342 * @param componentIndex 343 * a {@code non-null} component index 344 * @return the same builder instance 345 */ 346 public FirmwarePayloadBuilder componentIndex(String componentIndex) { 347 Util.requireNonEmpty(componentIndex, "componentIndex"); 348 this.componentIndex = componentIndex; 349 return this; 350 } 351 352 /** 353 * Retrieve the storage id of the firmware component. 354 * 355 * @return the storage id 356 */ 357 public FirmwareIdentifier getStorageId() { 358 return storageId; 359 } 360 361 /** 362 * Set the storage id. 363 * 364 * @param id 365 * a {@code non-null} storage id 366 * @return the same builder instance 367 */ 368 public FirmwarePayloadBuilder storageId(FirmwareIdentifier id) { 369 Objects.requireNonNull(id, "storageId"); 370 this.storageId = id; 371 return this; 372 } 373 374 /** 375 * Retrieve the conditions of the firmware payload. 376 * 377 * @return the conditions 378 */ 379 public List<FirmwareRequirement<FirmwareCondition>> getConditions() { 380 return conditions; 381 } 382 383 /** 384 * Adds a new condition to the list of conditions. 385 * 386 * @param condition 387 * the condition to add 388 * @return the same builder instance 389 */ 390 public FirmwarePayloadBuilder addCondition(FirmwareRequirement<FirmwareCondition> condition) { 391 Objects.requireNonNull(condition, "condition"); 392 this.conditions.add(condition); 393 return this; 394 } 395 396 /** 397 * Retrieve the directives of the firmware payload. 398 * 399 * @return the directives 400 */ 401 public List<FirmwareRequirement<FirmwareDirective>> getDirectives() { 402 return directives; 403 } 404 405 /** 406 * Adds a new directive to the list of directives. 407 * 408 * @param directive 409 * the directive to add 410 * @return the same builder instance 411 */ 412 public FirmwarePayloadBuilder addDirective(FirmwareRequirement<FirmwareDirective> directive) { 413 Objects.requireNonNull(directive, "directive"); 414 this.directives.add(directive); 415 return this; 416 } 417 418 // /** 419 // * Retrieve the targetDependency of the firmware component. 420 // * 421 // * @return the targetDependency 422 // */ 423 // public VersionedDependency getTargetDependency() { 424 // return targetDependency; 425 // } 426 // 427 // /** 428 // * Set the component targetDependency. 429 // * 430 // * @param targetDependency 431 // * a {@code non-null} targetDependency 432 // * @return the same builder instance 433 // */ 434 // public FirmwarePayloadBuilder targetDependency(VersionedDependency 435 // targetDependency) { 436 // Objects.requireNonNull(targetDependency, "targetDependency"); 437 // this.targetDependency = targetDependency; 438 // return this; 439 // } 440 441 // /** 442 // * Retrieve the targetMinimalVersion of the firmware component. 443 // * 444 // * @return the targetMinimalVersion 445 // */ 446 // public MinimalVersion getTargetMinimalVersion() { 447 // return targetMinimalVersion; 448 // } 449 // 450 // /** 451 // * Set the component targetMinimalVersion. 452 // * 453 // * @param targetMinimalVersion 454 // * a {@code non-null} targetMinimalVersion 455 // * @return the same builder instance 456 // */ 457 // public FirmwarePayloadBuilder targetMinimalVersion(MinimalVersion 458 // targetMinimalVersion) { 459 // Objects.requireNonNull(targetDependency, "targetDependency"); 460 // this.targetMinimalVersion = targetMinimalVersion; 461 // return this; 462 // } 463 464 // /** 465 // * Retrieve the relationships of the firmware payload. 466 // * 467 // * @return the relationships 468 // */ 469 // public List<FirmwarePayloadRelationship> getRelationships() { 470 // return relationships; 471 // } 472 // 473 // /** 474 // * Adds a new relationship to the list of relationships. 475 // * 476 // * @param relationship 477 // * the relationship to add 478 // * @return the same builder instance 479 // */ 480 // public FirmwarePayloadBuilder addRelationship(FirmwarePayloadRelationship 481 // relationship) { 482 // Objects.requireNonNull(relationship, "relationship"); 483 // this.relationships.add(relationship); 484 // return this; 485 // } 486 487 /** 488 * Retrieve the firmwarePackage of the firmware component. 489 * 490 * @return the targetMinimalVersion 491 */ 492 public FirmwarePayloadPackage getFirmwarePackage() { 493 return firmwarePackage; 494 } 495 496 /** 497 * Set the component firmwarePackage. 498 * 499 * @param firmwarePackage 500 * a {@code non-null} firmwarePackage 501 * @return the same builder instance 502 */ 503 public FirmwarePayloadBuilder firmwarePackage(FirmwarePayloadPackage firmwarePackage) { 504 Objects.requireNonNull(firmwarePackage, "firmwarePackage"); 505 this.firmwarePackage = firmwarePackage; 506 return this; 507 } 508 509 @Override 510 public void validate() throws ValidationException { 511 validateNonNull("id", id); 512 validateNonNull("formatType", formatType); 513 validateNonNull("size", size); 514 validateNonEmpty("digests", digests); 515 validateNonNull("storageId", storageId); 516 validateNonEmpty("conditions", conditions); 517 } 518 519 @Override 520 public void reset() { 521 // TODO: implement 522 } 523 }