/* * Copyright (C) 2013 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.policy.rule; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.intel.mtwilson.policy.BaseRule; import com.intel.mtwilson.policy.HostReport; import com.intel.mtwilson.policy.RuleResult; import com.intel.mtwilson.policy.fault.TagCertificateExpired; import com.intel.mtwilson.policy.fault.TagCertificateMissing; import com.intel.mtwilson.policy.fault.TagCertificateNotTrusted; import com.intel.mtwilson.policy.fault.TagCertificateNotYetValid; import com.intel.mtwilson.tag.model.X509AttributeCertificate; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Date; /** * * @author jbuhacoff */ @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonIgnoreProperties(ignoreUnknown=true) public class TagCertificateTrusted extends BaseRule { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TagCertificateTrusted.class); private X509Certificate[] trustedAuthorityCerts; protected TagCertificateTrusted() { } // for desearializing jackson public TagCertificateTrusted(X509Certificate[] trustedAuthorityCerts) { this.trustedAuthorityCerts = trustedAuthorityCerts; } @Override public RuleResult apply(HostReport hostReport) { RuleResult report = new RuleResult(this); if (hostReport.tagCertificate == null) { log.debug("Tag certificate is NULL"); report.fault(new TagCertificateMissing()); } else { Date today = new Date(); boolean validCaSignature = false; for (int i = 0; i < trustedAuthorityCerts.length && !validCaSignature; i++) { X509Certificate ca = trustedAuthorityCerts[i]; try { if (hostReport.tagCertificate.getIssuer().equalsIgnoreCase(ca.getIssuerX500Principal().getName())) { if (hostReport.tagCertificate.isValid(ca)) { // NOTE: CA certificate must be valid for the start date and end date of the tag certificate's validity - we don't let a CA generate certs for a period when the CA itself is expired. // if this rule is too strict in practice we can remove it log.debug("Verifying CA start date : {} with tag certificate start date : {}", ca.getNotBefore(), hostReport.tagCertificate.getNotBefore()); ca.checkValidity(hostReport.tagCertificate.getNotBefore()); log.debug("Verifying CA end date : {} with tag certificate end date : {}", ca.getNotAfter(), hostReport.tagCertificate.getNotAfter()); ca.checkValidity(hostReport.tagCertificate.getNotAfter()); validCaSignature = true; } else { log.debug("TagCertificate is not valid"); } } else { log.debug("Issuer name mismatch : {} vs {}", hostReport.tagCertificate.getIssuer(), ca.getIssuerX500Principal().getName()); } } catch (Exception e) { //CertificateExpiredException | CertificateNotYetValidException e) { log.debug("Failed to verify tag signature with CA: {}", e.getMessage()); // suppressing because maybe another cert in the list is a valid signer } } if (!validCaSignature) { log.debug("Adding fault for invalid tagcertificate"); report.fault(new TagCertificateNotTrusted()); } else { // we found a trusted ca and validated the tag certificate; now check the validity period of the tag certificate if (today.before(hostReport.tagCertificate.getNotBefore())) { log.debug("Adding fault for tagCertificate not yet valid"); report.fault(new TagCertificateNotYetValid(hostReport.tagCertificate.getNotBefore())); } if (today.after(hostReport.tagCertificate.getNotAfter())) { log.debug("Adding fault for tagCertificate already expired"); report.fault(new TagCertificateExpired(hostReport.tagCertificate.getNotAfter())); } } } return report; } @Override public String toString() { return "AIK certificate is signed by trusted authority"; } }