+ checkOperation(context.type(), CSSM_ALGCLASS_NONE);
+ switch (passThroughId) {
+ case CSSM_APPLESCPDL_CSP_GET_KEYHANDLE:
+ {
+ // inData unused, must be NULL
+ if (inData)
+ CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
+
+ // outData required, must be pointer-to-pointer-to-KeyHandle
+ KeyHandle &result = Required(reinterpret_cast<KeyHandle *>(outData));
+
+ // we'll take the key from the context
+ const CssmKey &key =
+ context.get<const CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+
+ // all ready
+ result = lookupKey(key).keyHandle();
+ break;
+ }
+ case CSSM_APPLECSP_KEYDIGEST:
+ {
+ // inData unused, must be NULL
+ if (inData)
+ CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
+
+ // outData required
+ Required(outData);
+
+ // take the key from the context, convert to KeyHandle
+ const CssmKey &key =
+ context.get<const CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+ KeyHandle keyHandle = lookupKey(key).keyHandle();
+
+ // allocate digest holder on app's behalf
+ CSSM_DATA *digest = alloc<CSSM_DATA>(sizeof(CSSM_DATA));
+ digest->Data = NULL;
+ digest->Length = 0;
+
+ // go
+ try {
+ clientSession().getKeyDigest(keyHandle, CssmData::overlay(*digest));
+ }
+ catch(...) {
+ free(digest);
+ throw;
+ }
+ *outData = digest;
+ break;
+ }
+
+ default:
+ CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID);
+ }