try {
signatureRecord = newSignatureRecord(v);
// validate
signatureRecord.validate();
} catch (IllegalStateException e) {
throw new PermFailException("Invalid signature record: "+e.getMessage(), e);
}
// Specification say we MAY refuse to verify the signature.
if (signatureRecord.getSignatureTimestamp() != null) {
long signedTime = signatureRecord.getSignatureTimestamp().longValue();
long elapsed = (System.currentTimeMillis()/1000 - signedTime);
if (elapsed < -3600*24*365*3) {
throw new PermFailException("Signature date is more than "
+ -elapsed/(3600*24*365) + " years in the future.");
} else if (elapsed < -3600*24*30*3) {
throw new PermFailException("Signature date is more than "
+ -elapsed/(3600*24*30) + " months in the future.");
} else if (elapsed < -3600*24*3) {
throw new PermFailException("Signature date is more than "
+ -elapsed/(3600*24) + " days in the future.");
} else if (elapsed < -3600*3) {
throw new PermFailException("Signature date is more than "
+ -elapsed/3600 + " hours in the future.");
} else if (elapsed < -60*3) {
throw new PermFailException("Signature date is more than "
+ -elapsed/60 + " minutes in the future.");
} else if (elapsed < 0) {
throw new PermFailException("Signature date is "
+ elapsed + " seconds in the future.");
}
}
// TODO here we could check more parameters for
// validation before running a network operation like the
// dns lookup.
// e.g: the canonicalization method could be checked now.
PublicKeyRecord publicKeyRecord = publicRecordLookup(signatureRecord);
List<CharSequence> signedHeadersList = signatureRecord.getHeaders();
byte[] decoded = signatureRecord.getSignature();
signatureVerify(messageHeaders, signatureRecord, decoded,
publicKeyRecord, signedHeadersList);
// we track all canonicalizations+limit+bodyHash we
// see so to be able to check all of them in a single
// stream run.
BodyHasherImpl bhj = newBodyHasher(signatureRecord);
bodyHashJobs.put(signatureField, bhj);
} else {
throw new PermFailException(
"unexpected bad signature field");
}
} catch (TempFailException e) {
signatureExceptions.put(signatureField, e);
} catch (PermFailException e) {
signatureExceptions.put(signatureField, e);
} catch (RuntimeException e) {
signatureExceptions.put(signatureField, new PermFailException(
"Unexpected exception processing signature", e));
}
}
if (bodyHashJobs.isEmpty()) {
if (signatureExceptions.size() > 0) {
throw prepareException(signatureExceptions);
} else {
throw new PermFailException("Unexpected condition with "+fields);
}
}
return new CompoundBodyHasher(bodyHashJobs, signatureExceptions);
}