Verify file signature with kSecCSConsiderExpiration

Hi,


I use SecStaticCodeCheckValidity(staticCode, kSecCSConsiderExpiration, NULL) to verify file signature. My understanding is if timestamp exists in the signature, the signing time will be used for validation. Otherwise, the "now" time will be used for validation. I use codesign utility to sign the file with "--timestamp=none" so that no timestamp generated (I found kSecCodeInfoTime/"signed time" in signature, which I belive is internal signing time that specified by the signer).

I then change system time to future time and make sure the signing certs in keychain are expired. I expected SecStaticCodeCheckValidity() returns errSecCertificateExpired, but it actually returns errSecSuccess. Did I do anything wrong here?

I’ve not delved into this part of the system previously, but I suspect that, when signing the program, you’ll need to do more than remove the timestamp, but rather you’ll need to pass in the

expires
flag (equivalent to
kSecCodeSignatureForceExpiration
).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I looked at open source of StaticCode API in security framework. It looks like the flags kSecCSConsiderExpiration and kSecCodeSignatureForceExpiration are both considered for expiration check.


void SecStaticCode::validateDirectory()

{

...

mValidationExpired = verifySignature();

...

#if TARGET_OS_OSX

if (mValidationResult == errSecSuccess) {

if (mValidationExpired)

if ((mValidationFlags & kSecCSConsiderExpiration)

|| (codeDirectory()->flags & kSecCodeSignatureForceExpiration))

MacOSError::throwMe(CSSMERR_TP_CERT_EXPIRED);

} else

MacOSError::throwMe(mValidationResult);

#endif

}


bool SecStaticCode::verifySignature()

{

...

MacOSError::check(SecTrustGetCssmResultCode(mTrust, &result));

// if we have a valid timestamp, CMS validates against (that) signing time and all is well.

// If we don't have one, may validate against *now*, and must be able to tolerate expiration.

if (mSigningTimestamp == 0) { // no timestamp available

if (((result == CSSMERR_TP_CERT_EXPIRED) || (result == CSSMERR_TP_CERT_NOT_VALID_YET))

&& !(actionData.ActionFlags & CSSM_TP_ACTION_ALLOW_EXPIRED)) {

CODESIGN_EVAL_STATIC_SIGNATURE_EXPIRED(this);

actionData.ActionFlags |= CSSM_TP_ACTION_ALLOW_EXPIRED; // (this also allows postdated certs)

continue; // retry validation while tolerating expiration

}

}

Security::Syslog::error("SecStaticCode: verification failed (trust result %d, error %d)", trustResult, (int)result);

MacOSError::throwMe(result);

....

return actionData.ActionFlags & CSSM_TP_ACTION_ALLOW_EXPIRED;

}


I am not sure if I use the API SecStaticCodeCheckValidity correctly. Does it require specific SecRequirementRef for expiration checking?

I am not sure if I use the API

SecStaticCodeCheckValidity
correctly. Does it require specific
SecRequirementRef
for expiration checking?

I wouldn’t have thought so; if you look at the Code Signing Requirement Language section of the Code Signing Guide, there’s no way to specify date requirements.

At this point my recommendation is that you open a DTS tech support incident and talk to our code signing API expert.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Verify file signature with kSecCSConsiderExpiration
 
 
Q