#include <Security/SecKeyPriv.h>
#include <utilities/SecCFWrappers.h>
#include <CoreFoundation/CFTimeZone.h>
+#include <Security/SecBasePriv.h>
#define HIDIGIT(v) (((v) / 10) + '0')
SECOidTag pubkAlgTag;
SecAsn1Item signature = { 0 };
OSStatus rv;
- PLArenaPool *poolp, *tmppoolp;
+ PLArenaPool *poolp, *tmppoolp = NULL;
const SECAlgorithmID *algID = NULL;
//CERTSubjectPublicKeyInfo *spki;
poolp = signerinfo->signedData->contentInfo.cmsg->poolp;
+ SecAsn1AlgId _algID;
+
switch (signerinfo->signerIdentifier.identifierType) {
case SecCmsSignerIDIssuerSN:
privkey = signerinfo->signingKey;
goto loser;
}
#else
- SecAsn1AlgId _algID = SecCertificateGetPublicKeyAlgorithmID(cert);
+ _algID = SecCertificateGetPublicKeyAlgorithmID(cert);
algID = &_algID;
#endif
break;
}
digestalgtag = SecCmsSignerInfoGetDigestAlgTag(signerinfo);
pubkAlgTag = SECOID_GetAlgorithmTag(algID);
+
+ /* we no longer support signing with MD5 */
+ if (digestalgtag == SEC_OID_MD5) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+
#if USE_CDSA_CRYPTO
if (signerinfo->signerIdentifier.identifierType == SecCmsSignerIDSubjectKeyID) {
SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
#endif
PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
+ tmppoolp = 0;
} else {
signature.Length = SecKeyGetSize(privkey, kSecKeySignatureSize);
signature.Data = PORT_ZAlloc(signature.Length);
SECITEM_FreeItem (&signature, PR_FALSE);
if (privkey)
SECKEY_DestroyPrivateKey(privkey);
+ if (tmppoolp)
+ PORT_FreeArena(tmppoolp, PR_FALSE);
return SECFailure;
}
{
if (PORT_GetError() == SEC_ERROR_UNTRUSTED_CERT)
{
- /* Signature or digest level verificationStatus errors should supercede certificate level errors, so only change the verificationStatus if the status was GoodSignature. */
- if (signerinfo->verificationStatus == SecCmsVSGoodSignature)
- signerinfo->verificationStatus = SecCmsVSSigningCertNotTrusted;
+ /* Signature or digest level verificationStatus errors should supercede certificate level errors, so only change the verificationStatus if the status was GoodSignature. */
+#if 0
+#warning DEBUG - SecCmsSignerInfoVerifyCertificate trusts everything!
+ if (signerinfo->verificationStatus == SecCmsVSGoodSignature) {
+ syslog(LOG_ERR, "SecCmsSignerInfoVerifyCertificate ignoring SEC_ERROR_UNTRUSTED_CERT");
+ rv = SECSuccess;
+ }
+#else
+ if (signerinfo->verificationStatus == SecCmsVSGoodSignature)
+ signerinfo->verificationStatus = SecCmsVSSigningCertNotTrusted;
+#endif
}
}
return SECSuccess;
}
+/*!
+ @function
+ @abstract Return the data in the signed Codesigning Hash Agility attribute.
+ @param sinfo SignerInfo data for this signer, pointer to a CFDataRef for attribute value
+ @discussion Returns a CFDataRef containing the value of the attribute
+ @result A return value of errSecInternal is an error trying to look up the oid.
+ A status value of success with null result data indicates the attribute was not present.
+ */
+OSStatus
+SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFDataRef *sdata)
+{
+ SecCmsAttribute *attr;
+ SecAsn1Item *value;
+
+ if (sinfo == NULL || sdata == NULL)
+ return errSecParam;
+
+ *sdata = NULL;
+
+ if (sinfo->hashAgilityAttrValue != NULL) {
+ *sdata = sinfo->hashAgilityAttrValue; /* cached copy */
+ return SECSuccess;
+ }
+
+ attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_HASH_AGILITY, PR_TRUE);
+
+ /* attribute not found */
+ if (attr == NULL || (value = SecCmsAttributeGetValue(attr)) == NULL)
+ return SECSuccess;
+
+ sinfo->hashAgilityAttrValue = CFDataCreate(NULL, value->Data, value->Length); /* make cached copy */
+ if (sinfo->hashAgilityAttrValue) {
+ *sdata = sinfo->hashAgilityAttrValue;
+ return SECSuccess;
+ }
+ return errSecAllocate;
+}
+
/*
* Return the signing cert of a CMS signerInfo.
*
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->signedData->contentInfo.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.
+ */
+ SecAsn1Item 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 = errSecInternal;
+ goto loser;
+ }
+
+ PORT_ArenaUnmark(poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return status;
+}
+
/*
* XXXX the following needs to be done in the S/MIME layer code
* after signature of a signerinfo is verified