|
1 | 1 | package hirs.attestationca.persist.provision;
|
2 | 2 |
|
| 3 | +import com.fasterxml.jackson.databind.ser.Serializers; |
3 | 4 | import com.google.protobuf.ByteString;
|
4 | 5 | import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
|
5 | 6 | import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
|
61 | 62 | import java.util.LinkedList;
|
62 | 63 | import java.util.List;
|
63 | 64 | import java.util.Map;
|
| 65 | +import java.util.Optional; |
| 66 | +import java.util.UUID; |
64 | 67 | import java.util.regex.Matcher;
|
65 | 68 | import java.util.regex.Pattern;
|
66 | 69 |
|
@@ -346,90 +349,151 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla
|
346 | 349 | dv.getHw().getManufacturer(),
|
347 | 350 | dv.getHw().getProductName());
|
348 | 351 | BaseReferenceManifest dbBaseRim = null;
|
349 |
| - SupportReferenceManifest support; |
| 352 | + SupportReferenceManifest support = null; |
350 | 353 | EventLogMeasurements measurements;
|
| 354 | + boolean isReplacement = false; |
| 355 | + String replacementRimId = ""; |
351 | 356 | String tagId = "";
|
352 | 357 | String fileName = "";
|
353 | 358 | Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
|
354 | 359 | Matcher matcher;
|
355 | 360 | MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
|
356 | 361 |
|
357 |
| - if (dv.getLogfileCount() > 0) { |
358 |
| - for (ByteString logFile : dv.getLogfileList()) { |
359 |
| - try { |
360 |
| - support = (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType( |
361 |
| - Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())), |
362 |
| - ReferenceManifest.SUPPORT_RIM); |
363 |
| - if (support == null) { |
364 |
| - support = new SupportReferenceManifest( |
365 |
| - String.format("%s.rimel", |
366 |
| - defaultClientName), |
367 |
| - logFile.toByteArray()); |
368 |
| - // this is a validity check |
369 |
| - new TCGEventLog(support.getRimBytes()); |
370 |
| - // no issues, continue |
371 |
| - support.setPlatformManufacturer(dv.getHw().getManufacturer()); |
372 |
| - support.setPlatformModel(dv.getHw().getProductName()); |
373 |
| - support.setFileName(String.format("%s_[%s].rimel", defaultClientName, |
374 |
| - support.getHexDecHash().substring( |
375 |
| - support.getHexDecHash().length() - NUM_OF_VARIABLES))); |
376 |
| - support.setDeviceName(dv.getNw().getHostname()); |
377 |
| - this.referenceManifestRepository.save(support); |
378 |
| - } else { |
379 |
| - log.info("Client provided Support RIM already loaded in database."); |
380 |
| - if (support.isArchived()) { |
381 |
| - support.restore(); |
382 |
| - support.resetCreateTime(); |
383 |
| - this.referenceManifestRepository.save(support); |
384 |
| - } |
385 |
| - } |
386 |
| - } catch (IOException ioEx) { |
387 |
| - log.error(ioEx); |
388 |
| - } catch (Exception ex) { |
389 |
| - log.error(String.format("Failed to load support rim: %s", ex.getMessage())); |
390 |
| - } |
391 |
| - } |
392 |
| - } else { |
393 |
| - log.warn(String.format("%s did not send support RIM file...", |
394 |
| - dv.getNw().getHostname())); |
395 |
| - } |
396 |
| - |
397 | 362 | if (dv.getSwidfileCount() > 0) {
|
398 | 363 | for (ByteString swidFile : dv.getSwidfileList()) {
|
399 | 364 | try {
|
400 | 365 | dbBaseRim = (BaseReferenceManifest) referenceManifestRepository
|
401 | 366 | .findByBase64Hash(Base64.getEncoder()
|
402 |
| - .encodeToString(messageDigest |
403 |
| - .digest(swidFile.toByteArray()))); |
| 367 | + .encodeToString(messageDigest |
| 368 | + .digest(swidFile.toByteArray()))); |
404 | 369 | if (dbBaseRim == null) {
|
| 370 | + /* |
| 371 | + Either the swidFile does not have a corresponding base RIM in the backend |
| 372 | + or it was deleted. Check if there is a replacement by comparing tagId against |
| 373 | + all other base RIMs, and then set the corresponding support rim's deviceName. |
| 374 | + */ |
405 | 375 | dbBaseRim = new BaseReferenceManifest(
|
406 | 376 | String.format("%s.swidtag",
|
407 | 377 | defaultClientName),
|
408 | 378 | swidFile.toByteArray());
|
| 379 | + List<BaseReferenceManifest> baseRims = referenceManifestRepository.findAllBaseRims(); |
| 380 | + for (BaseReferenceManifest bRim : baseRims) { |
| 381 | + if (bRim.getTagId().equals(dbBaseRim.getTagId())) { |
| 382 | + dbBaseRim = bRim; |
| 383 | + replacementRimId = dbBaseRim.getAssociatedRim().toString(); |
| 384 | + isReplacement = true; |
| 385 | + break; |
| 386 | + } |
| 387 | + } |
409 | 388 | dbBaseRim.setDeviceName(dv.getNw().getHostname());
|
410 | 389 | this.referenceManifestRepository.save(dbBaseRim);
|
411 |
| - } else { |
412 |
| - log.info("Client provided Base RIM already loaded in database."); |
413 |
| - /** |
414 |
| - * Leaving this as is for now, however can there be a condition |
415 |
| - * in which the provisioner sends swidtags without support rims? |
| 390 | + } else if (dbBaseRim.isArchived()) { |
| 391 | + /* |
| 392 | + This block accounts for RIMs that may have been soft-deleted (archived) |
| 393 | + in an older version of the ACA. |
416 | 394 | */
|
| 395 | + List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false); |
| 396 | + for (ReferenceManifest rim : rims) { |
| 397 | + if (rim.isBase() && rim.getTagId().equals(dbBaseRim.getTagId()) && |
| 398 | + rim.getCreateTime().after(dbBaseRim.getCreateTime())) { |
| 399 | + dbBaseRim.setDeviceName(null); |
| 400 | + dbBaseRim = (BaseReferenceManifest) rim; |
| 401 | + dbBaseRim.setDeviceName(dv.getNw().getHostname()); |
| 402 | + } |
| 403 | + } |
417 | 404 | if (dbBaseRim.isArchived()) {
|
418 |
| - dbBaseRim.restore(); |
419 |
| - dbBaseRim.resetCreateTime(); |
| 405 | + throw new Exception("Unable to locate an unarchived base RIM."); |
| 406 | + } else { |
420 | 407 | this.referenceManifestRepository.save(dbBaseRim);
|
421 | 408 | }
|
| 409 | + } else { |
| 410 | + dbBaseRim.setDeviceName(dv.getNw().getHostname()); |
| 411 | + this.referenceManifestRepository.save(dbBaseRim); |
422 | 412 | }
|
423 | 413 | tagId = dbBaseRim.getTagId();
|
424 | 414 | } catch (UnmarshalException e) {
|
425 | 415 | log.error(e);
|
| 416 | + } catch (Exception ex) { |
| 417 | + log.error(String.format("Failed to load base rim: %s", ex.getMessage())); |
426 | 418 | }
|
427 | 419 | }
|
428 | 420 | } else {
|
429 | 421 | log.warn(String.format("%s did not send swid tag file...",
|
430 | 422 | dv.getNw().getHostname()));
|
431 | 423 | }
|
432 | 424 |
|
| 425 | + if (dv.getLogfileCount() > 0) { |
| 426 | + for (ByteString logFile : dv.getLogfileList()) { |
| 427 | + try { |
| 428 | + support = (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType( |
| 429 | + Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())), |
| 430 | + ReferenceManifest.SUPPORT_RIM); |
| 431 | + if (support == null) { |
| 432 | + /* |
| 433 | + Either the logFile does not have a corresponding support RIM in the backend |
| 434 | + or it was deleted. The support RIM for a replacement base RIM is handled |
| 435 | + in the previous loop block. |
| 436 | + */ |
| 437 | + if (isReplacement) { |
| 438 | + Optional<ReferenceManifest> replacementRim = |
| 439 | + referenceManifestRepository.findById(UUID.fromString(replacementRimId)); |
| 440 | + if (replacementRim.isPresent()) { |
| 441 | + support = (SupportReferenceManifest) replacementRim.get(); |
| 442 | + support.setDeviceName(dv.getNw().getHostname()); |
| 443 | + } else { |
| 444 | + throw new Exception("Unable to locate support RIM " + replacementRimId); |
| 445 | + } |
| 446 | + } else { |
| 447 | + support = new SupportReferenceManifest( |
| 448 | + String.format("%s.rimel", |
| 449 | + defaultClientName), |
| 450 | + logFile.toByteArray()); |
| 451 | + // this is a validity check |
| 452 | + new TCGEventLog(support.getRimBytes()); |
| 453 | + // no issues, continue |
| 454 | + support.setPlatformManufacturer(dv.getHw().getManufacturer()); |
| 455 | + support.setPlatformModel(dv.getHw().getProductName()); |
| 456 | + support.setFileName(String.format("%s_[%s].rimel", defaultClientName, |
| 457 | + support.getHexDecHash().substring( |
| 458 | + support.getHexDecHash().length() - NUM_OF_VARIABLES))); |
| 459 | + } |
| 460 | + support.setDeviceName(dv.getNw().getHostname()); |
| 461 | + this.referenceManifestRepository.save(support); |
| 462 | + } else if (support.isArchived()) { |
| 463 | + /* |
| 464 | + This block accounts for RIMs that may have been soft-deleted (archived) |
| 465 | + in an older version of the ACA. |
| 466 | + */ |
| 467 | + List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false); |
| 468 | + for (ReferenceManifest rim : rims) { |
| 469 | + if (rim.isSupport() && |
| 470 | + rim.getTagId().equals(support.getTagId()) && |
| 471 | + rim.getCreateTime().after(support.getCreateTime())) { |
| 472 | + support.setDeviceName(null); |
| 473 | + support = (SupportReferenceManifest) rim; |
| 474 | + support.setDeviceName(dv.getNw().getHostname()); |
| 475 | + } |
| 476 | + } |
| 477 | + if (support.isArchived()) { |
| 478 | + throw new Exception("Unable to locate an unarchived support RIM."); |
| 479 | + } else { |
| 480 | + this.referenceManifestRepository.save(support); |
| 481 | + } |
| 482 | + } else { |
| 483 | + support.setDeviceName(dv.getNw().getHostname()); |
| 484 | + this.referenceManifestRepository.save(support); |
| 485 | + } |
| 486 | + } catch (IOException ioEx) { |
| 487 | + log.error(ioEx); |
| 488 | + } catch (Exception ex) { |
| 489 | + log.error(String.format("Failed to load support rim: %s", ex.getMessage())); |
| 490 | + } |
| 491 | + } |
| 492 | + } else { |
| 493 | + log.warn(String.format("%s did not send support RIM file...", |
| 494 | + dv.getNw().getHostname())); |
| 495 | + } |
| 496 | + |
433 | 497 | //update Support RIMs and Base RIMs.
|
434 | 498 | for (ByteString swidFile : dv.getSwidfileList()) {
|
435 | 499 | dbBaseRim = (BaseReferenceManifest) referenceManifestRepository
|
|
0 commit comments