]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_codesigning/lib/csutilities.cpp
Security-59306.120.7.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / csutilities.cpp
index c6f0231bf5fc6e38db9a60fb439642935330a7bf..774b6ee2c50d96f9f3992b284665380b5106239c 100644 (file)
 //
 // 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 {
 
@@ -67,9 +85,13 @@ void hashOfCertificate(const void *certData, size_t certLength, SHA1::Digest dig
 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
 }
 
 
@@ -83,7 +105,7 @@ bool verifyHash(SecCertificateRef cert, const Hashing::Byte *digest)
        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.
@@ -148,6 +170,65 @@ bool certificateHasPolicy(SecCertificateRef cert, const CSSM_OID &policyOid)
        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