/* * SecCmsAttributeArraySetAttr - set an attribute's value in a set of attributes */ OSStatus SecCmsAttributeArraySetAttr(PLArenaPool *poolp, SecCmsAttribute ***attrs, SECOidTag type, CSSM_DATA_PTR value, Boolean encoded) { SecCmsAttribute *attr; void *mark; mark = PORT_ArenaMark(poolp); /* see if we have one already */ attr = SecCmsAttributeArrayFindAttrByOidTag(*attrs, type, PR_FALSE); if (attr == NULL) { /* not found? create one! */ attr = SecCmsAttributeCreate(poolp, type, value, encoded); if (attr == NULL) goto loser; /* and add it to the list */ if (SecCmsArrayAdd(poolp, (void ***)attrs, (void *)attr) != SECSuccess) goto loser; } else { /* found, shove it in */ /* XXX we need a decent memory model @#$#$!#!!! */ attr->values[0] = value; attr->encoded = encoded; } PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* * SecCmsSignerInfoAddSigningTime - add the signing time to the * authenticated (i.e. signed) attributes of "signerinfo". * * This is expected to be included in outgoing signed * messages for email (S/MIME) but is likely useful in other situations. * * This should only be added once; a second call will do nothing. * * XXX This will probably just shove the current time into "signerinfo" * but it will not actually get signed until the entire item is * processed for encoding. Is this (expected to be small) delay okay? */ OSStatus SecCmsSignerInfoAddSigningTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t) { SecCmsAttribute *attr; CSSM_DATA stime; void *mark; PLArenaPool *poolp; poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); /* create new signing time attribute */ if (DER_CFDateToUTCTime(t, &stime) != SECSuccess) goto loser; if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) { SECITEM_FreeItem (&stime, PR_FALSE); goto loser; } SECITEM_FreeItem (&stime, PR_FALSE); if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* * SecCmsSignerInfoAddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the * authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. * * This is expected to be included in outgoing signed messages for email (S/MIME), * if compatibility with Microsoft mail clients is wanted. */ OSStatus SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertificateRef cert, SecKeychainRef keychainOrArray) { SecCmsAttribute *attr; CSSM_DATA_PTR smimeekp = NULL; void *mark; PLArenaPool *poolp; #if 0 CFTypeRef policy; /* verify this cert for encryption */ policy = CERT_PolicyForCertUsage(certUsageEmailRecipient); if (CERT_VerifyCert(keychainOrArray, cert, policy, CFAbsoluteTimeGetCurrent(), NULL) != SECSuccess) { CFRelease(policy); return SECFailure; } CFRelease(policy); #endif poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); smimeekp = SECITEM_AllocItem(poolp, NULL, 0); if (smimeekp == NULL) goto loser; /* create new signing time attribute */ if (SecSMIMECreateMSSMIMEEncKeyPrefs((SecArenaPoolRef)poolp, smimeekp, cert) != SECSuccess) goto loser; if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL) goto loser; if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
/*! @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". @discussion This is expected to be included in outgoing signed Apple code signatures. */ OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue) { SecCmsAttribute *attr; PLArenaPool *poolp = signerinfo->cmsg->poolp; void *mark = PORT_ArenaMark(poolp); OSStatus status = SECFailure; /* The value is required for this attribute. */ if (!attrValue) { status = errSecParam; goto loser; } /* * SecCmsAttributeCreate makes a copy of the data in value, so * we don't need to copy into the CSSM_DATA struct. */ CSSM_DATA value; value.Length = CFDataGetLength(attrValue); value.Data = (uint8_t *)CFDataGetBytePtr(attrValue); if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_HASH_AGILITY, &value, PR_FALSE)) == NULL) { status = errSecAllocate; goto loser; } if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) { status = errSecInternalError; goto loser; } PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return status; }
OSStatus SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken) { SecCmsAttribute *attr; PLArenaPool *poolp = signerinfo->cmsg->poolp; void *mark = PORT_ArenaMark(poolp); // We have already encoded this ourselves, so last param is PR_TRUE if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_PKCS9_TIMESTAMP_TOKEN, tstoken, PR_TRUE)) == NULL) goto loser; if (SecCmsSignerInfoAddUnauthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* * SecCmsSignerInfoAddSMIMECaps - add a SMIMECapabilities attribute to the * authenticated (i.e. signed) attributes of "signerinfo". * * This is expected to be included in outgoing signed * messages for email (S/MIME). */ OSStatus SecCmsSignerInfoAddSMIMECaps(SecCmsSignerInfoRef signerinfo) { SecCmsAttribute *attr; CSSM_DATA_PTR smimecaps = NULL; void *mark; PLArenaPool *poolp; poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); smimecaps = SECITEM_AllocItem(poolp, NULL, 0); if (smimecaps == NULL) goto loser; /* create new signing time attribute */ #if 1 // @@@ We don't do Fortezza yet. if (SecSMIMECreateSMIMECapabilities((SecArenaPoolRef)poolp, smimecaps, PR_FALSE) != SECSuccess) #else if (SecSMIMECreateSMIMECapabilities(poolp, smimecaps, PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess) #endif goto loser; if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL) goto loser; if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }