class PolicyUpdater {

    static boolean validateSignedPolicies(ZTSClient zts, PolicyUpdaterConfiguration configuration,
            DomainSignedPolicyData domainSignedPolicyData, String domain) {
        
        if (domainSignedPolicyData == null || domain == null) {
            throw new IllegalArgumentException("null parameters are not valid arguments");
        }
        
        LOG.info("Checking expiration time for:" + domain);

        Timestamp expires = domainSignedPolicyData.getSignedPolicyData().getExpires();
        if (System.currentTimeMillis() > expires.millis()) {
            LOG.error("Signed policy for domain:" + domain + " was expired.");
            return false;
        }

        // first we're going to verify the ZTS signature for the data
        
        LOG.info("Verifying ZTS signature for: " + domain);
        SignedPolicyData signedPolicyData = domainSignedPolicyData.getSignedPolicyData();
        
        LOG.debug("Policies retrieved from the ZTS server: " + signedPolicyData);

        String signature = domainSignedPolicyData.getSignature();
        String keyId     = domainSignedPolicyData.getKeyId();
        LOG.debug("validateSignedPolicies: domain=" + domain + " zts key id=" + keyId + " Digital ZTS signature=" + signature);

        PublicKey ztsPublicKey = configuration.getZtsPublicKey(zts, keyId);
        if (ztsPublicKey == null) {
            LOG.error("validateSignedPolicies: Missing ZTS Public key for id: " + keyId);
            return false;
        }
        
        boolean verified = Crypto.verify(SignUtils.asCanonicalString(signedPolicyData), ztsPublicKey, signature);
        if (verified == false) {
            LOG.error("Signed policy for domain:" + domain + " failed ZTS signature verification.");
            LOG.error("ZTS Signature: " + signature + ". Policies data returned from ZTS: " + signedPolicyData);
            return false;
        }
        
        // then we're going to verify the ZMS signature for the policy data
        
        LOG.info("Verifying ZMS signature for: " + domain);
        PolicyData policyData = signedPolicyData.getPolicyData();
       
        signature = signedPolicyData.getZmsSignature();
        LOG.debug("Digital ZMS signature: " + signature);
        keyId = signedPolicyData.getZmsKeyId();
        LOG.debug("Digital ZMS signature key Id: " + keyId);
        
        PublicKey zmsPublicKey = configuration.getZmsPublicKey(zts, keyId);
        if (zmsPublicKey == null) {
            LOG.error("Missing ZMS Public key with id: " + keyId);
            return false;
        }
        
        verified = Crypto.verify(SignUtils.asCanonicalString(policyData), zmsPublicKey, signature);
        if (verified == false) {
            LOG.error("Signed policy for domain:" + domain + " failed ZMS signature verification.");
            LOG.error("ZMS Signature: " + signature + ". Policies data returned from ZTS: " + policyData);
        }
        
        return verified;
    }

}