]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_smime/lib/cmssigdata.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_smime / lib / cmssigdata.c
index c072d3a96e69c459c305f8b8bce682b8c4c198cb..f63a7f80d70e9386b698fe7ac65cdbe6528ffdc4 100644 (file)
@@ -223,7 +223,7 @@ SecCmsSignedDataEncodeBeforeData(SecCmsSignedDataRef sigd)
 
 extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate;
 
-OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, 
+OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg, CSSM_DATA_PTR encDigest,
     SecAsn1TSAMessageImprint *messageImprint)
 {
     // Calculate hash of encDigest and put in messageImprint.hashedMessage
@@ -231,21 +231,17 @@ OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR e
     
     OSStatus status = SECFailure;
     
-    require(signedData && messageImprint, xit);
-       
-    SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
-    require(digestAlgorithms, xit);
+    require(signerInfo && digestAlg && messageImprint, xit);
 
-    SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms);
+    SecCmsDigestContextRef digcx = SecCmsDigestContextStartSingle(digestAlg);
     require(digcx, xit);
     require(encDigest, xit);
     
-    SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(signedData, 0);  // NB - assume 1 signer only!
-    messageImprint->hashAlgorithm = signerinfo->digestAlg;
+    messageImprint->hashAlgorithm = *digestAlg;
 
     SecCmsDigestContextUpdate(digcx, encDigest->Data, encDigest->Length);
     
-    require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signedData->cmsg->poolp,
+    require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signerInfo->cmsg->poolp,
         &messageImprint->hashedMessage), xit);
     
     status = SECSuccess;
@@ -354,7 +350,8 @@ static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinf
         The code for this is essentially the same code taht is done during a timestamp
         verify, except that we also need to check the nonce.
     */
-    require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, NULL, expectedNonce), xit);
+    CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo);
+    require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, encDigest, expectedNonce), xit);
 
     status = SecCmsSignerInfoAddTimeStamp(signerinfo, &respDER.timeStampTokenDER);
 
@@ -426,7 +423,7 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd)
     SecCmsContentInfoRef cinfo;
     SECOidTag digestalgtag;
     OSStatus ret = SECFailure;
-    OSStatus rv;
+    OSStatus rv = errSecSuccess;
     CSSM_DATA_PTR contentType;
     int certcount;
     int i, ci, n, rci, si;
@@ -440,9 +437,9 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd)
     /* did we have digest calculation going on? */
     if (cinfo->digcx) {
        rv = SecCmsDigestContextFinishMultiple(cinfo->digcx, (SecArenaPoolRef)poolp, &(sigd->digests));
+        cinfo->digcx = NULL;
        if (rv != SECSuccess)
            goto loser;         /* error has been set by SecCmsDigestContextFinishMultiple */
-       cinfo->digcx = NULL;
     }
 
     signerinfos = sigd->signerInfos;
@@ -500,7 +497,7 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd)
         // Calculate hash of encDigest and put in messageImprint.hashedMessage
         SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(sigd, 0);    // NB - assume 1 signer only!
         CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo);
-        require_noerr(createTSAMessageImprint(sigd, encDigest, &messageImprint), tsxit);
+        require_noerr(createTSAMessageImprint(signerinfo, &signerinfo->digestAlg, encDigest, &messageImprint), tsxit);
         
         // Callback to fire up XPC service to talk to TimeStamping server, etc.
         require_noerr(rv =(*sigd->cmsg->tsaCallback)(sigd->cmsg->tsaContext, &messageImprint,
@@ -617,8 +614,10 @@ SecCmsSignedDataDecodeAfterData(SecCmsSignedDataRef sigd)
 {
     /* did we have digest calculation going on? */
     if (sigd->contentInfo.digcx) {
-       if (SecCmsDigestContextFinishMultiple(sigd->contentInfo.digcx, (SecArenaPoolRef)sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess)
+        if (SecCmsDigestContextFinishMultiple(sigd->contentInfo.digcx, (SecArenaPoolRef)sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess) {
+            sigd->contentInfo.digcx = NULL;
            return SECFailure;  /* error has been set by SecCmsDigestContextFinishMultiple */
+        }
        sigd->contentInfo.digcx = NULL;
     }
     return SECSuccess;
@@ -634,6 +633,10 @@ SecCmsSignedDataDecodeAfterEnd(SecCmsSignedDataRef sigd)
     SecCmsSignerInfoRef *signerinfos;
     int i;
 
+    if (!sigd) {
+        return SECFailure;
+    }
+
     signerinfos = sigd->signerInfos;
 
     /* set cmsg and sigd backpointers for all the signerinfos */
@@ -746,8 +749,11 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
     CSSM_DATA_PTR contentType, digest;
     OSStatus status, status2;
 
-    cinfo = &(sigd->contentInfo);
+    if (sigd == NULL || sigd->signerInfos == NULL || i >= SecCmsSignedDataSignerInfoCount(sigd)) {
+        return errSecParam;
+    }
 
+    cinfo = &(sigd->contentInfo);
     signerinfo = sigd->signerInfos[i];
 
     /* Signature or digest level verificationStatus errors should supercede
@@ -756,32 +762,23 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
     /* Find digest and contentType for signerinfo */
     algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
     if (algiddata == NULL) {
-        return errSecInternalError; // shouldn't have happened, this is likely due to corrupted data
+        return errSecInvalidDigestAlgorithm;
     }
     
     digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset);
-       if(digest == NULL) {
-               /* 
-                * No digests; this probably had detached content the caller has to 
-                * deal with. 
-                * FIXME: need some error return for this (as well as many 
-                * other places in this library).
-                */
-               return errSecDataNotAvailable;
-       }
+    if(digest == NULL) {
+        /*
+         * No digests; this probably had detached content the caller has to
+         * deal with.
+         * FIXME: need some error return for this (as well as many
+         * other places in this library).
+         */
+        return errSecDataNotAvailable;
+    }
     contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
 
     /* verify signature */
-#if SECTRUST_OSX
-#warning STU: <rdar://21328501>
-       // timestamp policy is currently unsupported; use codesign policy only
-       #if !NDEBUG
-       syslog(LOG_ERR, "SecCmsSignedDataVerifySignerInfo: using codesign policy without timestamp verification");
-       #endif
-       CFTypeRef timeStampPolicies=SecPolicyCreateWithProperties(kSecPolicyAppleCodeSigning, NULL);
-#else
     CFTypeRef timeStampPolicies=SecPolicyCreateAppleTimeStampingAndRevocationPolicies(policies);
-#endif
     status = SecCmsSignerInfoVerifyWithPolicy(signerinfo, timeStampPolicies, digest, contentType);
     CFReleaseSafe(timeStampPolicies);
 
@@ -876,7 +873,7 @@ SecCmsSignedDataAddCertChain(SecCmsSignedDataRef sigd, SecCertificateRef cert)
     usage = certUsageEmailSigner;
 
     /* do not include root */
-    certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE);
+    certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE, PR_FALSE);
     if (certlist == NULL)
        return SECFailure;
 
@@ -961,11 +958,11 @@ SecCmsSignedDataGetDigestByAlgTag(SecCmsSignedDataRef sigd, SECOidTag algtag)
 {
     int idx;
 
-       if(sigd->digests == NULL) {
-               return NULL;
-       }
+    if(sigd == NULL || sigd->digests == NULL) {
+        return NULL;
+    }
     idx = SecCmsAlgArrayGetIndexByAlgTag(sigd->digestAlgorithms, algtag);
-    return sigd->digests[idx];
+    return (idx >= 0) ? sigd->digests[idx] : NULL;
 }
 
 /*
@@ -981,7 +978,8 @@ SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd,
 {
     int cnt, i, idx;
 
-    if (sigd->digestAlgorithms == NULL) {
+    /* Check input structure and items in structure */
+    if (sigd == NULL || sigd->digestAlgorithms == NULL || sigd->cmsg == NULL || sigd->cmsg->poolp == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
     }