-#if !TARGET_OS_EMBEDDED
- u_int32_t bytesEncrypted = 0;
- SecCertificateRef certificateRef = NULL;
- SecIdentitySearchRef idSearchRef = NULL;
- SecKeychainRef keychainRef = NULL;
- const CSSM_KEY *cssmKey = NULL;
- CSSM_CSP_HANDLE cspHandle = nil;
- CSSM_CC_HANDLE cssmContextHandle = nil;
- const CSSM_ACCESS_CREDENTIALS *credentials = NULL;
- //CSSM_SIZE bytesEncrypted = 0; //%%%%HWR fix this - need new headers on Leopard
- CSSM_DATA clearData;
- CSSM_DATA cipherData;
- CSSM_DATA remData;
- CSSM_CONTEXT_ATTRIBUTE newAttr;
-
- remData.Length = 0;
- remData.Data = 0;
-
- if (persistentCertRef) {
- // get cert from keychain
- status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef);
- if (status != noErr)
- goto end;
-
- // get keychain ref where cert is contained
- status = SecKeychainItemCopyKeychain((SecKeychainItemRef)certificateRef, &keychainRef);
- if (status != noErr)
- goto end;
-
- // get identity from the certificate
- status = SecIdentityCreateWithCertificate(keychainRef, certificateRef, &identityRef);
- if (status != noErr)
- goto end;
-
- } else {
-
- // copy system keychain
- status = CopySystemKeychain(&keychainRef);
- if (status != noErr)
- goto end;
-
- // serach for first identity in system keychain
- status = SecIdentitySearchCreate(keychainRef, CSSM_KEYUSE_SIGN, &idSearchRef);
- if (status != noErr)
- goto end;
-
- status = SecIdentitySearchCopyNext(idSearchRef, &identityRef);
- if (status != noErr)
- goto end;
-
- // get certificate from identity
- status = SecIdentityCopyCertificate(identityRef, &certificateRef);
- if (status != noErr)
- goto end;
- }
-
- // get private key from identity
- status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
- if (status != noErr)
- goto end;
-
- // get CSSM_KEY pointer from key ref
- status = SecKeyGetCSSMKey(privateKeyRef, &cssmKey);
- if (status != noErr)
- goto end;
-
- // get CSSM CSP handle
- status = SecKeychainGetCSPHandle(keychainRef, &cspHandle);
- if (status != noErr)
- goto end;
-
- // create CSSM credentials to unlock private key for encryption - no UI to be used
- status = SecKeyGetCredentials(privateKeyRef, CSSM_ACL_AUTHORIZATION_ENCRYPT,
- kSecCredentialTypeNoUI, &credentials);
- if (status != noErr)
- goto end;
-
- // create asymmetric context for encryption
- status = CSSM_CSP_CreateAsymmetricContext(cspHandle, CSSM_ALGID_RSA, credentials, cssmKey,
- CSSM_PADDING_PKCS1, &cssmContextHandle);
- if (status != noErr)
- goto end;
-
- // add mode attribute to use private key for encryption
- newAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
- newAttr.AttributeLength = sizeof(uint32);
- newAttr.Attribute.Data = (CSSM_DATA_PTR)CSSM_ALGMODE_PRIVATE_KEY;
- status = CSSM_UpdateContextAttributes(cssmContextHandle, 1, &newAttr);
- if(status != noErr)
- goto end;
-
- // and finally - encrypt data
- clearData.Length = hash->l;
- clearData.Data = (uint8 *)hash->v;
- cipherData.Length = 0;
- cipherData.Data = NULL;
- status = CSSM_EncryptData(cssmContextHandle, &clearData, 1, &cipherData, 1, &bytesEncrypted,
- &remData);
- if (status != noErr)
- goto end;
-
- if (remData.Length != 0) { // something didn't go right - should be zero
- status = -1;
- plog(LLV_ERROR, LOCATION, NULL,
- "unencrypted data remaining after encrypting hash.\n");
- goto end;
- }
-
- // alloc buffer for result
- sig = vmalloc(0);
- if (sig == NULL)
- goto end;
-
- sig->l = cipherData.Length;
- sig->v = (caddr_t)cipherData.Data;
-
-#else