AttestationResult TpmCertOperations::IsAkCertRenewalRequired()

in client-library/src/Attestation/AttestationClient/lib/TpmCertOperations.cpp [40:113]


AttestationResult TpmCertOperations::IsAkCertRenewalRequired(bool& is_ak_renewal_required) {
	AttestationResult result = AttestationResult(AttestationResult::ErrorCode::SUCCESS);
	try {
		std::string ak_cert;
		if ((result = ReadAkCertFromTpm(ak_cert)).code_ != AttestationResult::ErrorCode::SUCCESS) {
			return result;
		}

		size_t ak_cert_len = ak_cert.length();
		BIO* cert_bio = BIO_new(BIO_s_mem());
		BIO_write(cert_bio, ak_cert.c_str(), ak_cert_len);
		X509* ak_cert_x509 = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL);
		if (!ak_cert_x509) {
			CLIENT_LOG_ERROR("Unable to parse AK cert in memory");
			if(telemetry_reporting.get() != nullptr) {
        		telemetry_reporting->UpdateEvent("AkRenew", 
													"Unable to parse Ak Cert in memory", 
													TelemetryReportingBase::EventLevel::AK_RENEW_CERT_PARSING_FAILURE);
			}
			
			result.code_ = AttestationResult::ErrorCode::ERROR_AK_CERT_PARSING;
			result.description_ = "Failed to pass Ak cert in memory";
			return result;
		}

		if ((result = IsAkCertProvisioned(ak_cert_x509)).code_ != AttestationResult::ErrorCode::SUCCESS) {
			return result;
		}

		ASN1_TIME* not_after = X509_get_notAfter(ak_cert_x509);
		int diff_days = 0;
		if (!ASN1_TIME_diff(&diff_days, NULL, not_after, NULL)) {
			CLIENT_LOG_ERROR("ASN1_TIME_diff() failed while checking notAfter time.");
			if(telemetry_reporting.get() != nullptr) {
        		telemetry_reporting->UpdateEvent("AkRenew", 
													"Failed while checking notAfter time",
													TelemetryReportingBase::EventLevel::AK_RENEW_CERT_EXPIRY_CALCULATION_FAILURE);
			}

			result.code_ = AttestationResult::ErrorCode::ERROR_AK_CERT_PARSING;
			result.description_ = "Failed while checking Ak Cert validity";
			return result;
		}

		BIO_free(cert_bio);
		X509_free(ak_cert_x509);
		CLIENT_LOG_INFO("Number of days left in AK cert expiry - %d", diff_days);
		if(telemetry_reporting.get() != nullptr) {
        	telemetry_reporting->UpdateEvent("AkRenew", 
												std::to_string(-1*diff_days), 
												TelemetryReportingBase::EventLevel::AK_RENEW_CERT_DAYS_TILL_EXPIRY);
		}

		// Check if the certificate has already expired or is going to expire within next 90 days
		// If yes, return true
		if (diff_days >= AK_CERT_RENEWAL_THRESHOLD) {
			is_ak_renewal_required = true;
			return result;
		}
	}
	catch (const std::exception& e) {
		CLIENT_LOG_ERROR("Unexpected error occured in IsAkCertRenewalRequired method %s", e.what());
		if(telemetry_reporting.get() != nullptr) {
        	telemetry_reporting->UpdateEvent("AkRenew",
												"Unexpected Error in renewing AkCert",
												TelemetryReportingBase::EventLevel::AK_RENEW_UNEXPECTED_ERROR);
		}

		result.code_ = AttestationResult::ErrorCode::ERROR_AK_CERT_RENEW;
		result.description_ = e.what();
	}

	return result;
}