//
// csutilities - miscellaneous utilities for the code signing implementation
//
+
#include "csutilities.h"
+#include <libDER/DER_Encode.h>
+#include <libDER/DER_Keys.h>
+#include <libDER/asn1Types.h>
+#include <libDER/oids.h>
+#include <security_asn1/SecAsn1Coder.h>
+#include <security_asn1/SecAsn1Templates.h>
#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificate.h>
#include <utilities/SecAppleAnchorPriv.h>
#include <utilities/SecInternalReleasePriv.h>
-#include <security_codesigning/requirement.h>
+#include "requirement.h"
#include <security_utilities/hashing.h>
#include <security_utilities/debugging.h>
#include <security_utilities/errors.h>
#include <sys/utsname.h>
+extern "C" {
+
+/* Decode a choice of UTCTime or GeneralizedTime to a CFAbsoluteTime. Return
+ an absoluteTime if the date was valid and properly decoded. Return
+ NULL_TIME otherwise. */
+CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
+ size_t length);
+
+}
+
namespace Security {
namespace CodeSigning {
void hashOfCertificate(SecCertificateRef cert, SHA1::Digest digest)
{
assert(cert);
+#if TARGET_OS_OSX
CSSM_DATA certData;
MacOSError::check(SecCertificateGetData(cert, &certData));
hashOfCertificate(certData.Data, certData.Length, digest);
+#else
+ hashOfCertificate(SecCertificateGetBytePtr(cert), SecCertificateGetLength(cert), digest);
+#endif
}
return !memcmp(dig, digest, SHA1::digestLength);
}
-
+#if TARGET_OS_OSX
//
// Check to see if a certificate contains a particular field, by OID. This works for extensions,
// even ones not recognized by the local CL. It does not return any value, only presence.
return matched;
}
+
+CFDateRef certificateCopyFieldDate(SecCertificateRef cert, const CSSM_OID &policyOid)
+{
+ CFDataRef oidData = NULL;
+ CFDateRef value = NULL;
+ CFDataRef data = NULL;
+ SecAsn1CoderRef coder = NULL;
+ CSSM_DATA str = { 0 };
+ CFAbsoluteTime time = 0.0;
+ OSStatus status = 0;
+ bool isCritical;
+
+ oidData = CFDataCreateWithBytesNoCopy(NULL, policyOid.Data, policyOid.Length,
+ kCFAllocatorNull);
+
+ if (oidData == NULL) {
+ goto out;
+ }
+
+ data = SecCertificateCopyExtensionValue(cert, oidData, &isCritical);
+
+ if (data == NULL) {
+ goto out;
+ }
+
+ status = SecAsn1CoderCreate(&coder);
+ if (status != 0) {
+ goto out;
+ }
+
+ // We currently only support UTF8 strings.
+ status = SecAsn1Decode(coder, CFDataGetBytePtr(data), CFDataGetLength(data),
+ kSecAsn1UTF8StringTemplate, &str);
+ if (status != 0) {
+ goto out;
+ }
+
+ time = SecAbsoluteTimeFromDateContent(ASN1_GENERALIZED_TIME,
+ str.Data, str.Length);
+
+ if (time == 0.0) {
+ goto out;
+ }
+
+ value = CFDateCreate(NULL, time);
+out:
+ if (coder) {
+ SecAsn1CoderRelease(coder);
+ }
+ if (data) {
+ CFRelease(data);
+ }
+ if (oidData) {
+ CFRelease(oidData);
+ }
+
+ return value;
+}
+#endif
//
// Copyfile