+ CssmKey::Header tmpPubHeader, tmpPrivHeader;
+
+ pub->returnKey(*pubKey, tmpPubHeader);
+ if (!copyin(&tmpPubHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), pubHeader, pubHeaderLength))
+ CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+ Server::releaseWhenDone(*pubHeader);
+
+ priv->returnKey(*privKey, tmpPrivHeader);
+ if (!copyin(&tmpPrivHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), privHeader, privHeaderLength))
+ CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+ Server::releaseWhenDone(*privHeader);
+
+ END_IPC(CSP)
+}
+
+
+//
+// Key wrapping and unwrapping
+//
+kern_return_t ucsp_server_wrapKey(UCSP_ARGS, DATA_IN(context), KeyHandle hWrappingKey,
+ DATA_IN(cred), KeyHandle hKeyToBeWrapped,
+ DATA_IN(descriptiveData), DATA_OUT(wrappedKeyData))
+{
+ BEGIN_IPC(wrapKey)
+ CssmKey wrappedKey;
+ CopyOutContext ctx(context, contextLength);
+ CopyOutAccessCredentials creds(cred, credLength);
+ RefPointer<Key> subjectKey = Server::key(hKeyToBeWrapped);
+ RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
+ if ((ctx.context().algorithm() == CSSM_ALGID_NONE && subjectKey->attribute(CSSM_KEYATTR_SENSITIVE))
+ || !subjectKey->attribute(CSSM_KEYATTR_EXTRACTABLE))
+ CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+ pickDb(subjectKey, wrappingKey)->wrapKey(*ctx, creds, wrappingKey, *subjectKey, DATA(descriptiveData), wrappedKey);
+ Server::releaseWhenDone(wrappedKey.keyData().data());
+
+ if (!copyin(&wrappedKey, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEY), wrappedKeyData, wrappedKeyDataLength))
+ CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+
+ Server::releaseWhenDone(*wrappedKeyData);
+ END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, DbHandle db, DATA_IN(context),
+ KeyHandle hWrappingKey, DATA_IN(cred), DATA_IN(owner),
+ KeyHandle hPublicKey, DATA_IN(wrappedKeyData),
+ CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, DATA_OUT(descriptiveData),
+ KeyHandle *newKey, DATA_OUT(keyHeader)/*CssmKey::Header *newHeader*/)
+{
+ BEGIN_IPC(unwrapKey)
+ CopyOutContext ctx(context, contextLength);
+ CopyOutKey wrappedKey(wrappedKeyData, wrappedKeyDataLength);
+ CopyOutAccessCredentials creds(cred, credLength);
+ CopyOutEntryAcl owneracl(owner, ownerLength);
+ OutputData descriptiveDatas(descriptiveData, descriptiveDataLength);
+ RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
+ RefPointer<Key> unwrappedKey;
+ pickDb(Server::optionalDatabase(db), wrappingKey)->unwrapKey(*ctx, creds, owneracl,
+ wrappingKey, Server::optionalKey(hPublicKey),
+ usage, attrs, wrappedKey.key(), unwrappedKey, descriptiveDatas);
+
+ CssmKey::Header newHeader;
+ unwrappedKey->returnKey(*newKey, newHeader);
+ if (!copyin(&newHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+ CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+ Server::releaseWhenDone(*keyHeader);
+