snej@0: // snej@0: // MYKeychain.h snej@0: // MYCrypto snej@0: // snej@0: // Created by Jens Alfke on 3/23/09. snej@0: // Copyright 2009 Jens Alfke. All rights reserved. snej@0: // snej@0: snej@0: #import snej@2: #import "MYCryptoConfig.h" snej@3: @class MYSymmetricKey, MYPublicKey, MYPrivateKey, MYCertificate, MYSHA1Digest; snej@0: snej@0: snej@0: /** A Keychain, a secure database of cryptographic keys. snej@0: This class wraps the Security framework's SecKeychain API. */ snej@0: @interface MYKeychain : NSObject snej@0: { snej@1: @private snej@2: #if !MYCRYPTO_USE_IPHONE_API snej@0: SecKeychainRef _keychain; snej@0: #endif snej@0: } snej@0: snej@0: /** Returns a MYKeychain instance representing the user's default keychain. snej@0: This is the instance you'll usually want to add keys to. */ snej@0: + (MYKeychain*) defaultKeychain; snej@0: snej@0: /** Returns a MYKeychain instance representing the aggregate of all open keychains. snej@0: This is the instance you'll usually want to search for keys with. */ snej@0: + (MYKeychain*) allKeychains; snej@0: snej@0: #pragma mark SYMMETRIC KEYS: snej@0: snej@1: /** Randomly generates a new symmetric key, using the given algorithm and key-size in bits. snej@1: The key is persistently added to this keychain. */ snej@0: - (MYSymmetricKey*) generateSymmetricKeyOfSize: (unsigned)keySizeInBits snej@0: algorithm: (uint32_t/*CCAlgorithm*/)algorithm; snej@0: snej@1: /** Enumerates all of the symmetric keys in the keychain, as MYSymmetricKey objects. */ snej@0: - (NSEnumerator*) enumerateSymmetricKeys; snej@0: snej@0: #pragma mark PUBLIC KEYS: snej@0: snej@2: /** Imports a public key into the keychain, given its external representation snej@2: (as generated by -[MYPublicKey keyData].) */ snej@2: - (MYPublicKey*) importPublicKey: (NSData*)keyData; snej@2: snej@0: /** Looks up an existing public key with the given digest. snej@0: Returns nil if there is no such key in the keychain. snej@0: (This method does not look for keys embedded in certificates, only 'bare' keys.) */ snej@0: - (MYPublicKey*) publicKeyWithDigest: (MYSHA1Digest*)pubKeyDigest; snej@0: snej@0: /** Enumerates all public keys in the keychain. snej@0: (This method does not find keys embedded in certificates, only 'bare' keys.) */ snej@0: - (NSEnumerator*) enumeratePublicKeys; snej@0: snej@2: #pragma mark CERTIFICATES: snej@0: snej@2: /** Imports a certificate into the keychain, given its external representation. */ snej@2: - (MYCertificate*) importCertificate: (NSData*)data; snej@0: snej@0: /** Looks up an existing certificate with the given public-key digest. snej@1: Returns nil if there is no such certificate in the keychain. snej@1: (This method only looks for keys embedded in certificates, not 'bare' public keys.) */ snej@0: - (MYCertificate*) certificateWithDigest: (MYSHA1Digest*)pubKeyDigest; snej@0: snej@0: /** Enumerates all certificates in the keychain. */ snej@0: - (NSEnumerator*) enumerateCertificates; snej@0: snej@4: /** Enumerates all identities in the keychain. */ snej@4: - (NSEnumerator*) enumerateIdentities; snej@4: snej@0: #pragma mark KEY-PAIRS: snej@0: snej@0: /** Generates a new RSA key-pair and adds both keys to the keychain. snej@1: This is very slow -- it may take seconds, depending on the key size, CPU speed, snej@1: and other random factors. You may want to start some kind of progress indicator before snej@0: calling this method, so the user doesn't think the app has locked up! snej@0: @param keySize The RSA key length in bits. Must be a power of two. Longer keys are harder snej@0: to break, but operate more slowly and generate larger signatures. snej@0: 2048 is a good default choice. You could use 1024 if the data and signatures won't need snej@0: to stay secure for years; or you could use 4096 if you're extremely paranoid. */ snej@3: - (MYPrivateKey*) generateRSAKeyPairOfSize: (unsigned)keySize; snej@0: snej@2: /** Looks up an existing key-pair whose public key has the given digest. snej@2: Returns nil if there is no such key-pair in the keychain. snej@2: (This method does not look for public keys embedded in certificates, only 'bare' keys.) */ snej@3: - (MYPrivateKey*) privateKeyWithDigest: (MYSHA1Digest*)pubKeyDigest; snej@0: snej@2: /** Enumerates all key-pairs in the keychain. snej@2: (This method does not find keys embedded in certificates, only 'bare' keys.) */ snej@3: - (NSEnumerator*) enumeratePrivateKeys; snej@0: snej@0: snej@0: #pragma mark - snej@0: #pragma mark METHODS NOT SUPPORTED ON IPHONE: snej@0: snej@0: snej@2: /** @name Mac-Only snej@2: * Functionality not available on iPhone. snej@2: */ snej@2: //@{ snej@0: #if !TARGET_OS_IPHONE snej@0: jens@16: /** Sets whether the keychain is allowed to pop up panels to interact with the user, jens@16: for example to ask for permission to access keys. If user interaction is not jens@16: allowed, all such requests will fail. */ jens@16: + (void) setUserInteractionAllowed: (BOOL)allowed; jens@16: snej@2: /** Enumerates all public keys in the keychain that have the given alias string. */ snej@2: - (NSEnumerator*) symmetricKeysWithAlias: (NSString*)alias; snej@2: snej@2: /** Enumerates all public keys in the keychain that have the given alias string. */ snej@2: - (NSEnumerator*) publicKeysWithAlias: (NSString*)alias; snej@2: jens@26: - (NSEnumerator*) enumerateIdentitiesWithKeyUsage: (CSSM_KEYUSE)keyUsage; jens@26: snej@2: /** Imports a key-pair into the keychain, given the external representations snej@2: of both the public and private keys. snej@2: Since the private key data is wrapped (encrypted), the Security agent will prompt the user to enter snej@2: the passphrase. */ snej@3: - (MYPrivateKey*) importPublicKey: (NSData*)pubKeyData snej@4: privateKey: (NSData*)privKeyData; snej@2: snej@2: /** Imports a key-pair into the keychain, given the external representations snej@2: of both the public and private keys. snej@2: Since the private key data is wrapped (encrypted), the Security agent will prompt the user to enter snej@2: the passphrase. You can specify the title and prompt message for this alert panel. */ snej@3: - (MYPrivateKey*) importPublicKey: (NSData*)pubKeyData snej@4: privateKey: (NSData*)privKeyData snej@4: alertTitle: (NSString*)title snej@4: alertPrompt: (NSString*)prompt; snej@2: snej@5: /** Adds a certificate to this keychain. (It must not already belong to a keychain.) */ snej@5: - (BOOL) addCertificate: (MYCertificate*)certificate; snej@5: snej@2: /** Imports a certificate into the keychain, given its external representation. */ snej@2: - (MYCertificate*) importCertificate: (NSData*)data snej@2: type: (CSSM_CERT_TYPE) type snej@2: encoding: (CSSM_CERT_ENCODING) encoding; snej@2: snej@2: //@} jens@26: #else jens@26: /** @name iPhone-Only jens@26: * Functionality only available on iPhone. jens@26: */ jens@26: //@{ jens@26: jens@26: - (BOOL) removeAllCertificates; jens@26: - (BOOL) removeAllKeys; jens@26: jens@26: //@} snej@2: #endif snej@2: snej@2: snej@2: snej@2: /** @name Expert (Mac-Only) snej@2: * Advanced functionality, not available on iPhone. snej@2: */ snej@2: //@{ snej@2: #if !TARGET_OS_IPHONE snej@0: snej@0: /** Creates a MYKeychain for an existing SecKeychainRef. */ snej@0: - (id) initWithKeychainRef: (SecKeychainRef)keychainRef; snej@0: snej@0: /** Opens a keychain file. */ snej@0: + (MYKeychain*) openKeychainAtPath: (NSString*)path; snej@0: snej@0: /** Creates a new keychain file. */ snej@0: + (MYKeychain*) createKeychainAtPath: (NSString*)path snej@0: withPassword: (NSString*)password; snej@0: snej@0: /** Closes and deletes the keychain's file. You should not use this object any more. */ snej@0: - (BOOL) deleteKeychainFile; snej@0: snej@0: /** Returns the underlying SecKeychainRef for this keychain. snej@0: This will be NULL for the special allKeychains instance, because it doesn't snej@0: represent a single specific keychain. To handle that case, use the snej@0: keychainRefOrDefault property instead. */ snej@0: @property (readonly) SecKeychainRef keychainRef; snej@0: snej@0: /** Returns the underlying SecKeychainRef for this keychain. snej@0: The special allKeychains instance returns a reference to the default keychain, snej@0: as a convenience. */ snej@0: @property (readonly) SecKeychainRef keychainRefOrDefault; snej@0: snej@0: /** The path of this keychain's file. */ snej@0: @property (readonly) NSString* path; snej@0: snej@0: /** The underlying CSSM storage handle; used when calling CSSM APIs. */ snej@0: @property (readonly) CSSM_CSP_HANDLE CSPHandle; snej@0: snej@2: #endif snej@2: //@} snej@0: snej@0: @end snej@0: