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 <Foundation/Foundation.h>
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: 
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: 
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: //@}
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: