rv = SecCertificateGetAlgorithmID(cert,&algid);
} else {
PORT_Assert(pubKey);
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
+#if TARGET_OS_OSX
rv = SecKeyGetAlgorithmID(pubKey,&algid);
#else
/* TBD: Unify this code. Currently, iOS has an incompatible
break;
}
} else if (type == SecCmsRecipientIDSubjectKeyID){
- SecCmsKeyTransRecipientInfoEx *riExtra;
rid->id.subjectKeyID = PORT_ArenaNew(poolp, CSSM_DATA);
if (rid->id.subjectKeyID == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
break;
}
- SECITEM_CopyItem(poolp, rid->id.subjectKeyID, subjKeyID);
+ if (SECITEM_CopyItem(poolp, rid->id.subjectKeyID, subjKeyID)) {
+ rv = SECFailure;
+ PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
+ break;
+ }
if (rid->id.subjectKeyID->Data == NULL) {
rv = SECFailure;
PORT_SetError(SEC_ERROR_NO_MEMORY);
break;
}
- riExtra = &ri->ri.keyTransRecipientInfoEx;
- riExtra->version = 0;
- riExtra->pubKey = SECKEY_CopyPublicKey(pubKey);
- if (riExtra->pubKey == NULL) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- break;
- }
} else {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
NULL, pubKey, subjKeyID);
}
+/* This is exported out of the Security framework, but it's in
+ * SecCertificateInternal.h, which we don't have access to from
+ * the libsecurity_smime project. */
+CFDataRef SecCertificateGetSubjectKeyID(SecCertificateRef certificate);
+
SecCmsRecipientInfoRef
SecCmsRecipientInfoCreateWithSubjKeyIDFromCert(SecCmsMessageRef cmsg,
SecCertificateRef cert)
{
- SecPublicKeyRef pubKey = NULL;
+ SecKeyRef pubKey = NULL;
CSSM_DATA subjKeyID = {0, NULL};
SecCmsRecipientInfoRef retVal = NULL;
+ CFDataRef subjectKeyIDData = NULL;
+
if (!cmsg || !cert) {
return NULL;
}
- pubKey = CERT_ExtractPublicKey(cert);
- if (!pubKey) {
- goto done;
- }
- if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess ||
- subjKeyID.Data == NULL) {
- goto done;
- }
+
+ subjectKeyIDData = SecCertificateGetSubjectKeyID(cert);
+ if (!subjectKeyIDData)
+ goto done;
+ subjKeyID.Length =
+ CFDataGetLength(subjectKeyIDData);
+ subjKeyID.Data = (uint8_t *)CFDataGetBytePtr(subjectKeyIDData);
+
retVal = SecCmsRecipientInfoCreateWithSubjKeyID(cmsg, &subjKeyID, pubKey);
done:
if (pubKey)
&kari->ukm,
&kari->keyEncAlg,
&oiok->id.originatorPublicKey.publicKey);
- /* this is a BIT STRING */
- oiok->id.originatorPublicKey.publicKey.Length <<= 3;
break;
default:
switch (ri->recipientInfoType) {
case SecCmsRecipientInfoIDKeyTrans:
- encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg);
encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */
switch (encalgtag) {
case SEC_OID_NETSCAPE_SMIME_KEA:
/* FORTEZZA key exchange algorithm */
/* the supplemental data is in the parameters of encalg */
+ encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg);
bulkkey = SecCmsUtilDecryptSymKeyMISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg);
break;
#endif /* 0 */
}
break;
case SecCmsRecipientInfoIDKeyAgree:
- encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg);
encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
switch (encalgtag) {
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
/* Diffie-Helman key exchange */
case SEC_OID_DH_SINGLE_STD_SHA1KDF:
{
/* ephemeral-static ECDH */
+ enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
+ encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg);
SecCmsKeyAgreeRecipientInfo *kari = &ri->ri.keyAgreeRecipientInfo;
SecCmsOriginatorIdentifierOrKey *oiok = &kari->originatorIdentifierOrKey;
if(oiok->identifierType != SecCmsOriginatorIDOrKeyOriginatorPublicKey) {
dprintf("SEC_OID_EC_PUBLIC_KEY unwrap key: bad oiok.id\n");
+ error = SEC_ERROR_LIBRARY_FAILURE;
goto loser;
}
SecCmsOriginatorPublicKey *opk = &oiok->id.originatorPublicKey;
/* FIXME - verify opk->algorithmIdentifier here? */
CSSM_DATA senderPubKey = opk->publicKey;
- /* Bit string, convert here */
- senderPubKey.Length = (senderPubKey.Length + 7) >> 3;
CSSM_DATA_PTR ukm = &kari->ukm;
bulkkey = SecCmsUtilDecryptSymKeyECDH(privkey, enckey, ukm, encalg, bulkalgtag, &senderPubKey);
break;
}
break;
case SecCmsRecipientInfoIDKEK:
- encalg = &(ri->ri.kekRecipientInfo.keyEncAlg);
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.kekRecipientInfo.encKey);
/* not supported yet */
error = SEC_ERROR_UNSUPPORTED_KEYALG;
goto loser;
return bulkkey;
loser:
+ PORT_SetError(error);
return NULL;
}