]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_smime/lib/SecCMS.c
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_smime / lib / SecCMS.c
index 6c3b49330d3a6b4c1a41b5b7679bbf7250a49d5b..53e74aacda780f28bfb9a5a2379ef46e94e99f0c 100644 (file)
@@ -54,6 +54,9 @@ CFTypeRef kSecCMSAdditionalCerts = CFSTR("kSecCMSAdditionalCerts");
 CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes");
 CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate");
 CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts");
 CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes");
 CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate");
 CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts");
+CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility");
+CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2");
+CFTypeRef kSecCMSExpirationDate = CFSTR("kSecCMSExpirationDate");
 
 CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm");
 CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC");
 
 CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm");
 CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC");
@@ -182,6 +185,20 @@ out:
     return status;
 }
 
     return status;
 }
 
+OSStatus SecCMSSignDataAndAttributes(SecIdentityRef identity, CFDataRef data, bool detached,
+                                     CFMutableDataRef signed_data, CFDictionaryRef signed_attributes)
+{
+    return SecCMSSignDataOrDigestAndAttributes(identity, data, detached, false, SEC_OID_SHA1,
+                                               signed_data, signed_attributes, SecCmsCMCertChain, NULL);
+}
+
+OSStatus SecCMSSignDigestAndAttributes(SecIdentityRef identity, CFDataRef digest,
+                                       CFMutableDataRef signed_data, CFDictionaryRef signed_attributes)
+{
+    return SecCMSSignDataOrDigestAndAttributes(identity, digest, true, true, SEC_OID_SHA1,
+                                               signed_data, signed_attributes, SecCmsCMCertChain, NULL);
+}
+
 OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data,
                                 CFDictionaryRef parameters, CFDictionaryRef signed_attributes,
                                 CFMutableDataRef signed_data)
 OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data,
                                 CFDictionaryRef parameters, CFDictionaryRef signed_attributes,
                                 CFMutableDataRef signed_data)
@@ -373,6 +390,29 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det
             }
         }
 
             }
         }
 
+        CFDataRef hash_agility_value = NULL;
+        if (errSecSuccess == SecCmsSignerInfoGetAppleCodesigningHashAgility(sigd->signerInfos[0], &hash_agility_value)) {
+            if (hash_agility_value) {
+                CFDictionarySetValue(attrs, kSecCMSHashAgility, hash_agility_value);
+            }
+        }
+
+        CFDictionaryRef hash_agility_values = NULL;
+        if (errSecSuccess == SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(sigd->signerInfos[0], &hash_agility_values)) {
+            if (hash_agility_values) {
+                CFDictionarySetValue(attrs, kSecCMSHashAgilityV2, hash_agility_values);
+            }
+        }
+
+        CFAbsoluteTime expiration_time;
+        if (errSecSuccess == SecCmsSignerInfoGetAppleExpirationTime(sigd->signerInfos[0], &expiration_time)) {
+            CFDateRef expiration_date = CFDateCreate(NULL, expiration_time);
+            if (expiration_date) {
+                CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date);
+                CFRetainSafe(expiration_date);
+            }
+        }
+        
         *signed_attributes = attrs;
         if (certs) CFRelease(certs);
     }
         *signed_attributes = attrs;
         if (certs) CFRelease(certs);
     }
@@ -419,6 +459,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) {
     SecCmsSignedDataRef sigd = NULL;
     CFMutableArrayRef certs = NULL;
 
     SecCmsSignedDataRef sigd = NULL;
     CFMutableArrayRef certs = NULL;
 
+    if (!message) {
+        return NULL;
+    }
+
     CSSM_DATA encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) };
     require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out);
     /* expected to be a signed data message at the top level */
     CSSM_DATA encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) };
     require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out);
     /* expected to be a signed data message at the top level */
@@ -443,8 +487,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) {
     }
 
 out:
     }
 
 out:
-    if (cmsg)
-        SecCmsMessageDestroy(cmsg);
+    if (cmsg) { SecCmsMessageDestroy(cmsg); }
+    if (certs && CFArrayGetCount(certs) < 1) {
+        CFReleaseNull(certs);
+    }
 
     return certs;
 }
 
     return certs;
 }
@@ -618,9 +664,12 @@ OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof,
             (SecCertificateRef)CFArrayGetValueAtIndex(recipient_or_cfarray_thereof, dex);
             SecCmsRecipientInfoRef rinfo;
             require(rinfo = SecCmsRecipientInfoCreate(cmsg, recip), out);
             (SecCertificateRef)CFArrayGetValueAtIndex(recipient_or_cfarray_thereof, dex);
             SecCmsRecipientInfoRef rinfo;
             require(rinfo = SecCmsRecipientInfoCreate(cmsg, recip), out);
+            require_noerr(SecCmsEnvelopedDataAddRecipient(envd, rinfo), out);
         }
     } else if (CFGetTypeID(recipient_or_cfarray_thereof) == SecCertificateGetTypeID()) {
         }
     } else if (CFGetTypeID(recipient_or_cfarray_thereof) == SecCertificateGetTypeID()) {
-        require(SecCmsRecipientInfoCreate(cmsg, (SecCertificateRef)recipient_or_cfarray_thereof), out);
+        SecCmsRecipientInfoRef rinfo;
+        require(rinfo = SecCmsRecipientInfoCreate(cmsg, (SecCertificateRef)recipient_or_cfarray_thereof), out);
+        require_noerr(SecCmsEnvelopedDataAddRecipient(envd, rinfo), out);
     } else
         goto out;
 
     } else
         goto out;