X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurityd/lib/ssclient.h diff --git a/Security/libsecurityd/lib/ssclient.h b/Security/libsecurityd/lib/ssclient.h new file mode 100644 index 00000000..43835294 --- /dev/null +++ b/Security/libsecurityd/lib/ssclient.h @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2000-2008,2011-2013 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// +// ssclient - SecurityServer client interface library +// +// This interface is private to the Security system. It is not a public interface, +// and it may change at any time. You have been warned. +// +#ifndef _H_SSCLIENT +#define _H_SSCLIENT + +#include "sscommon.h" +#include +#include +#include + +#ifdef __cplusplus + +#include +#include +#include +#include +#include "ssnotify.h" + + +namespace Security { +namespace SecurityServer { + +#endif //__cplusplus + + +// +// Unique-identifier blobs for key objects +// +typedef struct KeyUID { + uint8 signature[20]; +} KeyUID; + + +// +// Maximum length of hash (digest) arguments (bytes) +// +#define maxUcspHashLength 64 + + +// +// Authorization blobs +// +typedef struct AuthorizationBlob { + uint32 data[2]; + +#ifdef __cplusplus + bool operator < (const AuthorizationBlob &other) const + { return memcmp(data, other.data, sizeof(data)) < 0; } + + bool operator == (const AuthorizationBlob &other) const + { return memcmp(data, other.data, sizeof(data)) == 0; } + + size_t hash() const { //@@@ revisit this hash + return data[0] ^ data[1] << 3; + } +#endif +} AuthorizationBlob; + + +// +// Initial-setup data for versioning etc. +// +typedef struct { + uint32_t order; + uint32_t version; +} ClientSetupInfo; + +#define SSPROTOVERSION 20000 + + +// +// Database parameter structure +// +typedef struct { + uint32_t idleTimeout; // seconds idle timout lock + uint8_t lockOnSleep; // lock keychain when system sleeps +} DBParameters; + + +#ifdef __cplusplus + + +// +// A client connection (session) +// +class ClientSession : public ClientCommon { +public: + ClientSession(Allocator &standard = Allocator::standard(), + Allocator &returning = Allocator::standard()); + virtual ~ClientSession(); + +public: + void activate(); + void reset(); + +public: + // use this only if you know what you're doing... + void contactName(const char *name); + const char *contactName() const; + + static GenericHandle toIPCHandle(CSSM_HANDLE h) { + // implementation subject to change + if (h & (CSSM_HANDLE(~0) ^ GenericHandle(~0))) + CssmError::throwMe(CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); + return h & GenericHandle(~0); + } + + +public: + // + // common database interface + // + void authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type, const AccessCredentials *cred); + void releaseDb(DbHandle db); + + // + // External database interface + // + DbHandle openToken(uint32 ssid, const AccessCredentials *cred, const char *name = NULL); + + RecordHandle insertRecord(DbHandle db, + CSSM_DB_RECORDTYPE recordType, + const CssmDbRecordAttributeData *attributes, + const CssmData *data); + void deleteRecord(DbHandle db, RecordHandle record); + void modifyRecord(DbHandle db, RecordHandle &record, + CSSM_DB_RECORDTYPE recordType, + const CssmDbRecordAttributeData *attributesToBeModified, + const CssmData *dataToBeModified, + CSSM_DB_MODIFY_MODE modifyMode); + + RecordHandle findFirst(DbHandle db, + const CssmQuery &query, + SearchHandle &outSearchHandle, + CssmDbRecordAttributeData *inOutAttributes, + CssmData *outData, KeyHandle &key); + RecordHandle findNext(SearchHandle searchHandle, + CssmDbRecordAttributeData *inOutAttributes, + CssmData *inOutData, KeyHandle &key); + void findRecordHandle(RecordHandle record, + CssmDbRecordAttributeData *inOutAttributes, + CssmData *inOutData, KeyHandle &key); + void releaseSearch(SearchHandle searchHandle); + void releaseRecord(RecordHandle record); + + void getDbName(DbHandle db, std::string &name); + void setDbName(DbHandle db, const std::string &name); + + // + // Internal database interface + // + DbHandle createDb(const DLDbIdentifier &dbId, + const AccessCredentials *cred, const AclEntryInput *owner, + const DBParameters ¶ms); + DbHandle cloneDbForSync(const CssmData &secretsBlob, DbHandle srcDb, + const CssmData &agentData); + DbHandle recodeDbForSync(DbHandle dbToClone, DbHandle srcDb); + DbHandle authenticateDbsForSync(const CssmData &dbHandleArray, const CssmData &agentData); + void commitDbForSync(DbHandle srcDb, DbHandle cloneDb, CssmData &blob, Allocator &alloc); + DbHandle decodeDb(const DLDbIdentifier &dbId, + const AccessCredentials *cred, const CssmData &blob); + void encodeDb(DbHandle db, CssmData &blob, Allocator &alloc); + void encodeDb(DbHandle db, CssmData &blob) { return encodeDb(db, blob, returnAllocator); } + void setDbParameters(DbHandle db, const DBParameters ¶ms); + void getDbParameters(DbHandle db, DBParameters ¶ms); + void changePassphrase(DbHandle db, const AccessCredentials *cred); + void lock(DbHandle db); + void lockAll(bool forSleep); + void unlock(DbHandle db); + void unlock(DbHandle db, const CssmData &passPhrase); + void stashDb(DbHandle db); + void stashDbCheck(DbHandle db); + bool isLocked(DbHandle db); + void verifyKeyStorePassphrase(uint32_t retries); + void resetKeyStorePassphrase(const CssmData &passphrase); + void changeKeyStorePassphrase(); + +public: + // + // Key objects + // + void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, Allocator &alloc); + void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid = NULL) + { return encodeKey(key, blob, uid, returnAllocator); } + KeyHandle decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header); + void recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb, CssmData &blob); + void releaseKey(KeyHandle key); + + CssmKeySize queryKeySizeInBits(KeyHandle key); + uint32 getOutputSize(const Security::Context &context, KeyHandle key, + uint32 inputSize, bool encrypt = true); + + void getKeyDigest(KeyHandle key, CssmData &digest, Allocator &alloc); + void getKeyDigest(KeyHandle key, CssmData &digest) + { return getKeyDigest(key, digest, returnAllocator); } + + + // key wrapping and unwrapping + void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, + const AccessCredentials *cred, + const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc); + void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, + const AccessCredentials *cred, + const CssmData *descriptiveData, CssmWrappedKey &wrappedKey) + { return wrapKey(context, key, keyToBeWrapped, cred, + descriptiveData, wrappedKey, returnAllocator); } + + void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey, + const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, + CssmData &data, KeyHandle &newKey, CssmKey::Header &newKeyHeader, Allocator &alloc); + void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey, + const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, CssmData &data, + KeyHandle &newKey, CssmKey::Header &newKeyHeader) + { return unwrapKey(db, context, key, publicKey, wrappedKey, keyUsage, keyAttr, + cred, owner, data, newKey, newKeyHeader, returnAllocator); } + + // key generation and derivation + void generateKey(DbHandle db, const Security::Context &context, uint32 keyUsage, uint32 keyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &newKey, CssmKey::Header &newHeader); + void generateKey(DbHandle db, const Security::Context &context, + uint32 pubKeyUsage, uint32 pubKeyAttr, + uint32 privKeyUsage, uint32 privKeyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &pubKey, CssmKey::Header &pubHeader, + KeyHandle &privKey, CssmKey::Header &privHeader); + void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey, + uint32 keyUsage, uint32 keyAttr, CssmData ¶m, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); + void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey, + uint32 keyUsage, uint32 keyAttr, CssmData ¶m, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &newKey, CssmKey::Header &newHeader) + { return deriveKey(db, context, baseKey, keyUsage, keyAttr, param, cred, owner, newKey, newHeader, returnAllocator); } + //void generateAlgorithmParameters(); // not implemented + + void generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc); + void generateRandom(const Security::Context &context, CssmData &data) + { return generateRandom(context, data, returnAllocator); } + + // encrypt/decrypt + void encrypt(const Security::Context &context, KeyHandle key, + const CssmData &in, CssmData &out, Allocator &alloc); + void encrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) + { return encrypt(context, key, in, out, returnAllocator); } + void decrypt(const Security::Context &context, KeyHandle key, + const CssmData &in, CssmData &out, Allocator &alloc); + void decrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) + { return decrypt(context, key, in, out, returnAllocator); } + + // signatures + void generateSignature(const Security::Context &context, KeyHandle key, + const CssmData &data, CssmData &signature, Allocator &alloc, + CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE); + void generateSignature(const Security::Context &context, KeyHandle key, + const CssmData &data, CssmData &signature, CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE) + { return generateSignature(context, key, data, signature, returnAllocator, signOnlyAlgorithm); } + void verifySignature(const Security::Context &context, KeyHandle key, + const CssmData &data, const CssmData &signature, + CSSM_ALGORITHMS verifyOnlyAlgorithm = CSSM_ALGID_NONE); + + // MACs + void generateMac(const Security::Context &context, KeyHandle key, + const CssmData &data, CssmData &mac, Allocator &alloc); + void generateMac(const Security::Context &context, KeyHandle key, + const CssmData &data, CssmData &mac) + { return generateMac(context, key, data, mac, returnAllocator); } + void verifyMac(const Security::Context &context, KeyHandle key, + const CssmData &data, const CssmData &mac); + + // key ACL management + void getKeyAcl(KeyHandle key, const char *tag, + uint32 &count, AclEntryInfo * &info, Allocator &alloc); + void getKeyAcl(KeyHandle key, const char *tag, + uint32 &count, AclEntryInfo * &info) + { return getKeyAcl(key, tag, count, info, returnAllocator); } + void changeKeyAcl(KeyHandle key, const AccessCredentials &cred, const AclEdit &edit); + void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner, Allocator &alloc); + void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner) + { return getKeyOwner(key, owner, returnAllocator); } + void changeKeyOwner(KeyHandle key, const AccessCredentials &cred, + const AclOwnerPrototype &edit); + + // database ACL management + void getDbAcl(DbHandle db, const char *tag, + uint32 &count, AclEntryInfo * &info, Allocator &alloc); + void getDbAcl(DbHandle db, const char *tag, + uint32 &count, AclEntryInfo * &info) + { return getDbAcl(db, tag, count, info, returnAllocator); } + void changeDbAcl(DbHandle db, const AccessCredentials &cred, const AclEdit &edit); + void getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc); + void getDbOwner(DbHandle db, AclOwnerPrototype &owner) + { return getDbOwner(db, owner, returnAllocator); } + void changeDbOwner(DbHandle db, const AccessCredentials &cred, + const AclOwnerPrototype &edit); + + // database key manipulations + void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb, + uint32 keyUsage, uint32 keyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); + void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb, + uint32 keyUsage, uint32 keyAttr, + const AccessCredentials *cred, const AclEntryInput *owner, + KeyHandle &newKey, CssmKey::Header &newHeader) + { return extractMasterKey(db, context, sourceDb, keyUsage, keyAttr, cred, owner, + newKey, newHeader, returnAllocator); } + +public: + // Authorization API support + void authCreate(const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, + AuthorizationFlags flags,AuthorizationBlob &result); + void authRelease(const AuthorizationBlob &auth, AuthorizationFlags flags); + void authCopyRights(const AuthorizationBlob &auth, + const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, + AuthorizationFlags flags, AuthorizationItemSet **result); + void authCopyInfo(const AuthorizationBlob &auth, const char *tag, AuthorizationItemSet * &info); + void authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm); + void authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth); + +public: + // Session API support + void setSessionUserPrefs(SecuritySessionId sessionId, uint32_t userPreferencesLength, const void *userPreferences); + +public: + // Notification core support + void postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data); + + // low-level callback (C form) + typedef OSStatus ConsumeNotification(NotificationDomain domain, NotificationEvent event, + const void *data, size_t dataLength, void *context); + +public: + // AuthorizationDB API + void authorizationdbGet(const AuthorizationString rightname, CssmData &rightDefinition, Allocator &alloc); + void authorizationdbSet(const AuthorizationBlob &auth, const AuthorizationString rightname, uint32_t rightdefinitionLength, const void *rightdefinition); + void authorizationdbRemove(const AuthorizationBlob &auth, const AuthorizationString rightname); + +public: + // securityd helper support + void childCheckIn(Port serverPort, Port taskPort); + +public: + // miscellaneous administrative calls + void addCodeEquivalence(const CssmData &oldCode, const CssmData &newCode, + const char *name, bool forSystem = false); + void removeCodeEquivalence(const CssmData &code, const char *name, bool forSystem = false); + void setAlternateSystemRoot(const char *path); + +public: + // temporary hack to deal with "edit acl" pseudo-error returns + typedef void DidChangeKeyAclCallback(void *context, ClientSession &clientSession, + KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); + void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context); + +public: + // Code Signing hosting interface + void registerHosting(mach_port_t hostingPort, SecCSFlags flags); + mach_port_t hostingPort(pid_t pid); + + SecGuestRef createGuest(SecGuestRef host, + uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags); + void setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes); + void removeGuest(SecGuestRef host, SecGuestRef guest); + + void selectGuest(SecGuestRef guest); + SecGuestRef selectedGuest() const; + +private: + static Port findSecurityd(); + void getAcl(AclKind kind, GenericHandle key, const char *tag, + uint32 &count, AclEntryInfo * &info, Allocator &alloc); + void changeAcl(AclKind kind, GenericHandle key, + const AccessCredentials &cred, const AclEdit &edit); + void getOwner(AclKind kind, GenericHandle key, + AclOwnerPrototype &owner, Allocator &alloc); + void changeOwner(AclKind kind, GenericHandle key, + const AccessCredentials &cred, const AclOwnerPrototype &edit); + + static OSStatus consumerDispatch(NotificationDomain domain, NotificationEvent event, + const void *data, size_t dataLength, void *context); + + void notifyAclChange(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); + + void returnAttrsAndData(CssmDbRecordAttributeData *inOutAttributes, + CssmDbRecordAttributeData *attrs, CssmDbRecordAttributeData *attrsBase, mach_msg_type_number_t attrsLength, + CssmData *inOutData, void *dataPtr, mach_msg_type_number_t dataLength); +private: + DidChangeKeyAclCallback *mCallback; + void *mCallbackContext; + + static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator + + struct Thread { + Thread() : registered(false), notifySeq(0), + currentGuest(kSecNoGuest), lastGuest(kSecNoGuest) { } + operator bool() const { return registered; } + + ReceivePort replyPort; // dedicated reply port (send right held by SecurityServer) + bool registered; // has been registered with SecurityServer + uint32 notifySeq; // notification sequence number + + SecGuestRef currentGuest; // last set guest path + SecGuestRef lastGuest; // last transmitted guest path + }; + + struct Global { + Global(); + Port serverPort; + RefPointer myself; + ThreadNexus thread; + }; + + static ModuleNexus mGlobal; + static const char *mContactName; + static SecGuestRef mDedicatedGuest; +}; + + +} // end namespace SecurityServer +} // end namespace Security + +#endif //__cplusplus + + +#endif //_H_SSCLIENT