├── .gitignore ├── spotlight_interface ├── Version ├── English.lproj │ ├── schema.strings │ └── InfoPlist.strings ├── version.plist ├── schema.xml ├── Info.plist └── GetMetadataForFile.m ├── delicious.icns ├── English.lproj ├── InfoPlist.strings ├── Localizable.strings ├── MainMenu.nib │ ├── objects.nib │ ├── keyedobjects.nib │ ├── info.nib │ └── classes.nib └── LogIn.nib │ ├── keyedobjects.nib │ ├── info.nib │ └── classes.nib ├── Keychain ├── English.lproj │ ├── InfoPlist.strings │ ├── Keyblob Types.strings │ ├── Key Classes.strings │ ├── Certificate Encodings.strings │ ├── Certificate Types.strings │ ├── Key Usage.strings │ ├── Key Attributes.strings │ ├── BER Names.strings │ ├── Misc Names.strings │ ├── Keyblob Formats.strings │ ├── Algorithm Modes.strings │ └── Algorithms.strings ├── Generate Documentation.command ├── FileUtilities.h ├── How to create an identity.rtf ├── Info-Keychain__Upgraded_.plist ├── Hashcash.h ├── MultiThreading.h ├── CertificateExtensions.h ├── Usage.rtf ├── Readme.rtf ├── CertificateExtensions.m ├── KeychainUtils.h ├── CSSMErrors.h ├── Policy.h ├── NSDataAdditions.h ├── MultiThreading.m ├── License.rtf ├── Policy.m ├── TrustedApplication.h ├── CertificateBundle.h ├── Trust.h ├── MutableKey.h ├── KeychainUtils.m ├── TrustedApplication.m ├── CSSMDefaults.m ├── CSSMInfo.h ├── FileUtilities.m ├── Identity.m ├── NSCachedObject.m ├── CertificateGeneration.h ├── KeychainSearch.h ├── SKeyPlus.m ├── UtilitySupport.h ├── SKeyPlus.h ├── CertificateBundle.m ├── ABPersonAdditions.h ├── NSCachedObject.h ├── Identity.h ├── CSSMInfo.m ├── Access.m ├── Trust.m ├── CSSMUtils.h └── CSSMDefaults.h ├── delimport_Prefix.pch ├── main.m ├── DIFileController.h ├── DILoginController.h ├── DILoginController.m ├── DIBookmarksController.h ├── Info.plist ├── README.md └── DIFileController.m /.gitignore: -------------------------------------------------------------------------------- 1 | output.html 2 | -------------------------------------------------------------------------------- /spotlight_interface/Version: -------------------------------------------------------------------------------- 1 | Release 2 2 | June 6, 2004 -------------------------------------------------------------------------------- /delicious.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/delicious.icns -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /English.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/English.lproj/Localizable.strings -------------------------------------------------------------------------------- /English.lproj/MainMenu.nib/objects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/English.lproj/MainMenu.nib/objects.nib -------------------------------------------------------------------------------- /English.lproj/LogIn.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/English.lproj/LogIn.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Keychain/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/Keychain/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /English.lproj/MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/English.lproj/MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /spotlight_interface/English.lproj/schema.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/spotlight_interface/English.lproj/schema.strings -------------------------------------------------------------------------------- /spotlight_interface/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttscoff/delimport-pinboard/HEAD/spotlight_interface/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /Keychain/Generate Documentation.command: -------------------------------------------------------------------------------- 1 | cd ~/Documents/Distributed\ Services/Keychain\ Framework/ 2 | headerdoc2html -o Documentation * 3 | gatherheaderdoc Documentation 4 | -------------------------------------------------------------------------------- /delimport_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'delimport' target in the 'delimport' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 28.04.05. 6 | // Copyright Ian Henderson 2005. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Keyblob Types.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_KEYBLOB_TYPEs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the type, generally a single word. */ 5 | 6 | 0 = "Raw"; 7 | 1 = "Reference"; 8 | 2 = "Wrapped"; -------------------------------------------------------------------------------- /Keychain/English.lproj/Key Classes.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_KEYCLASSs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the key class. */ 5 | 6 | 0 = "Public key"; 7 | 1 = "Private key"; 8 | 2 = "Session key"; 9 | 3 = "Secret part"; -------------------------------------------------------------------------------- /Keychain/FileUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // FileUtilities.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sun Jan 25 2004. 6 | // Copyright (c) 2004 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | NSData* digestOfPath(NSString* path, CSSM_ALGORITHMS algorithm); 14 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Certificate Encodings.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_CERT_ENCODINGs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the encoding, generally a single word. */ 5 | 6 | 1 = "Custom"; 7 | 2 = "BER"; 8 | 3 = "DER"; 9 | 4 = "NDR"; 10 | 5 = "SEXPR"; 11 | 6 = "PGP"; -------------------------------------------------------------------------------- /English.lproj/LogIn.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 277 354 356 240 0 0 1280 778 7 | IBFramework Version 8 | 446.1 9 | IBSystem Version 10 | 8S2161 11 | 12 | 13 | -------------------------------------------------------------------------------- /English.lproj/LogIn.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | { 4 | ACTIONS = {logIn = id; quit = id; }; 5 | CLASS = DILoginController; 6 | LANGUAGE = ObjC; 7 | OUTLETS = {passField = NSTextField; userField = NSTextField; }; 8 | SUPERCLASS = NSWindowController; 9 | }, 10 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 11 | ); 12 | IBVersion = 1; 13 | } -------------------------------------------------------------------------------- /DIFileController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DIFileController.h 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 28.04.05. 6 | // Copyright 2005 Ian Henderson. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface DIFileController : NSObject { 13 | 14 | } 15 | 16 | - (void)saveDictionary:(NSDictionary *)dictionary; 17 | 18 | - (void)saveDictionaries:(NSSet *)dictionaries; 19 | - (void)deleteDictionaries:(NSSet *)dictionaries; 20 | 21 | - (BOOL)openFile:(NSString *)filename; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /DILoginController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DILoginController.h 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 01.05.05. 6 | // Copyright 2005 Ian Henderson. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface DILoginController : NSWindowController { 13 | IBOutlet NSTextField *userField; 14 | IBOutlet NSTextField *passField; 15 | } 16 | 17 | - (IBAction)logIn:sender; 18 | - (IBAction)quit:sender; 19 | - (void)getUsername:(NSString **)username password:(NSString **)password; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Certificate Types.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_CERT_TYPEs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the type, generally a single word. */ 5 | 6 | 7 | 1 = "X509 (v1)"; 8 | 2 = "X509 (v2)"; 9 | 3 = "X509 (v3)"; 10 | 4 = "PGP"; 11 | 5 = "SPKI"; 12 | 6 = "SDSI (v1)"; 13 | 8 = "Intel"; 14 | 9 = "X509 Attribute"; 15 | 10 = "X9 Attribute"; 16 | 11 = "Tuple"; 17 | 12 = "ACL Entry"; 18 | 32766 = "Multiple"; -------------------------------------------------------------------------------- /spotlight_interface/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 3 7 | CFBundleShortVersionString 8 | 1.0 9 | CFBundleVersion 10 | 1.0 11 | ProjectName 12 | DevToolsWizardTemplates 13 | SourceVersion 14 | 3070000 15 | 16 | 17 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Key Usage.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_KEYUSEs. */ 2 | 3 | /* The key is the bit mask value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. Note that since the key attribute is a bit map, you must mask out other bits first. */ 4 | /* The value is human-readable name for the key usage. */ 5 | 6 | 0x00000001 = "Encrypt"; 7 | 0x00000002 = "Decrypt"; 8 | 0x00000004 = "Sign"; 9 | 0x00000008 = "Verify"; 10 | 0x00000010 = "Sign Recovery"; 11 | 0x00000020 = "Verify Recovery"; 12 | 0x00000040 = "Wrap"; 13 | 0x00000080 = "Unwrap"; 14 | 0x00000100 = "Derive"; 15 | 16 | 0x80000000 = "Any"; -------------------------------------------------------------------------------- /English.lproj/MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 130 91 356 240 0 0 1440 878 7 | IBEditorPositions 8 | 9 | 29 10 | 159 527 141 44 0 0 1440 878 11 | 12 | IBFramework Version 13 | 437.0 14 | IBOpenObjects 15 | 16 | 29 17 | 18 | IBSystem Version 19 | 8A428 20 | 21 | 22 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Key Attributes.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_KEYATTR_FLAGSs. */ 2 | 3 | /* The key is the bit mask value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. Note that since the key attribute is a bit map, you must mask out other bits first. */ 4 | /* The value is human-readable name for the key attribute. */ 5 | 6 | 0x00000001 = "Permanent"; 7 | 0x00000002 = "Private"; 8 | 0x00000004 = "Modifiable"; 9 | 0x00000008 = "Sensitive"; 10 | 0x00000010 = "Always sensitive"; 11 | 0x00000020 = "Extractable"; 12 | 0x00000040 = "Never extractable"; 13 | 14 | 0x10000000 = "Return Data"; 15 | 0x20000000 = "Return Reference"; 16 | 0x40000000 = "Return None"; -------------------------------------------------------------------------------- /English.lproj/MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | { 4 | ACTIONS = {logIn = id; }; 5 | CLASS = DIBookmarksController; 6 | LANGUAGE = ObjC; 7 | OUTLETS = { 8 | fileController = DIFileController; 9 | loginPanel = NSPanel; 10 | passField = NSTextField; 11 | userField = NSTextField; 12 | }; 13 | SUPERCLASS = NSObject; 14 | }, 15 | { 16 | ACTIONS = {testStuff = id; }; 17 | CLASS = DIFileController; 18 | LANGUAGE = ObjC; 19 | SUPERCLASS = NSObject; 20 | }, 21 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 22 | ); 23 | IBVersion = 1; 24 | } -------------------------------------------------------------------------------- /DILoginController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DILoginController.m 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 01.05.05. 6 | // Copyright 2005 Ian Henderson. All rights reserved. 7 | // 8 | 9 | #import "DILoginController.h" 10 | 11 | 12 | @implementation DILoginController 13 | 14 | 15 | - (IBAction)quit:sender 16 | { 17 | [NSApp terminate:self]; 18 | } 19 | 20 | - init 21 | { 22 | return [super initWithWindowNibName:@"LogIn"]; 23 | } 24 | 25 | - (void)getUsername:(NSString **)username password:(NSString **)password 26 | { 27 | [self showWindow:self]; 28 | [[self window] makeKeyAndOrderFront:self]; 29 | [[self window] center]; 30 | [NSApp runModalForWindow:[self window]]; 31 | *username = [userField stringValue]; 32 | *password = [passField stringValue]; 33 | [self close]; 34 | } 35 | 36 | - (IBAction)logIn:sender 37 | { 38 | [NSApp stopModal]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /DIBookmarksController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DIBookmarksController.h 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 30.04.05. 6 | // Copyright 2005 Ian Henderson. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define DIMinutesBetweenChecks @"MinutesBetweenChecks" 12 | #define DIDisplayErrorMessages @"DisplayErrorMessages" 13 | 14 | @class DIFileController, DILoginController; 15 | 16 | @interface DIBookmarksController : NSObject { 17 | DIFileController *fileController; 18 | DILoginController *loginController; 19 | 20 | NSString *username; 21 | NSString *password; 22 | 23 | NSSet *bookmarks; 24 | NSDate *lastUpdate; 25 | NSDate *throttleTimepoint; 26 | } 27 | 28 | - (void)logIn; 29 | - (void)updateList:(NSTimer *)timer; 30 | - (void)setBookmarks:(NSSet *)newMarks; 31 | 32 | - (void) setupTimer:(NSTimer*) timer; 33 | - (NSTimeInterval) currentUpdateInterval; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Keychain/English.lproj/BER Names.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for BER encoding parameters etc. */ 2 | 3 | /* The key is the numeric value as defined in x509defs.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the value, generally a single word. */ 5 | 6 | 1 = "BOOL"; 7 | 2 = "int"; 8 | 3 = "Bit String"; 9 | 4 = "Octet String"; 10 | 5 = "NULL"; 11 | 6 = "OID"; 12 | 7 = "Object Descriptor"; 13 | 8 = "External"; 14 | 9 = "Real"; 15 | 10 = "Enumerated"; 16 | 12 = "PKIX UTF8 String"; 17 | 16 = "Sequence"; 18 | 17 = "Set"; 19 | 18 = "Numeric String"; 20 | 19 = "Printable String"; 21 | 20 = "T61/Teletex String"; 22 | 21 = "Videotex String"; 23 | 22 = "IA5 String"; 24 | 23 = "UTC Time"; 25 | 24 = "Generalized Time"; 26 | 25 = "Graphic String"; 27 | 26 = "ISO646/Visible String"; 28 | 27 = "General String"; 29 | 28 = "PKIX Universal String"; 30 | 30 = "PKIX BMP String"; -------------------------------------------------------------------------------- /Keychain/How to create an identity.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\mac\ansicpg10000\cocoartf102 2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh9000\viewkind0 5 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural 6 | 7 | \f0\fs24 \cf0 Steps to create an identity:\ 8 | \ 9 | 0) Generate key pair, and add these to the keychain DLDB\ 10 | 1) Generate the hash for the public key, and attach this to the private key\ 11 | 2) Create the certificate, and insert it into the keychain using the Sec* functions as normal\ 12 | 3) Reinsert it with some extra attributes, including the public key hash\ 13 | \ 14 | \ 15 | \ 16 | 1) Gather together the cert and priv key (both already in keychain)\ 17 | 2) Generate the hash for the pub key in the certificate\ 18 | 3) Reinsert (?) the certificate into the keychain DLDB with the pub key hash attached\ 19 | 4) Attach the pub key hash to the priv key, and update it in the keychain DLDB} -------------------------------------------------------------------------------- /Keychain/Info-Keychain__Upgraded_.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Keychain 9 | CFBundleGetInfoString 10 | v0.0.1d1 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | Keychain.framework 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Keychain Framework 19 | CFBundlePackageType 20 | FMWK 21 | CFBundleShortVersionString 22 | v0.0.1d1 23 | CFBundleSignature 24 | Keyc 25 | CFBundleVersion 26 | 0.0.1d1 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /spotlight_interface/schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | kMDItemContentCreationDate 13 | 14 | 15 | kMDItemURL 16 | kMDItemContentCreationDate 17 | kMDItemContentModificationDate 18 | kMDItemDisplayName 19 | kMDItemKeywords 20 | kMDItemDescription 21 | kMDItemKind 22 | 23 | 24 | kMDItemURL 25 | kMDItemContentCreationDate 26 | kMDItemKeywords 27 | kMDItemDescription 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Misc Names.strings: -------------------------------------------------------------------------------- 1 | /* This file contains the names of various miscellaneous CSSM constants */ 2 | 3 | /* The key is the defined name of the constant */ 4 | /* The value is a brief name for the constant */ 5 | 6 | CSSM_KEYUSE_ANY = "Any"; 7 | CSSM_KEYUSE_ENCRYPT = "Encryption"; 8 | CSSM_KEYUSE_DECRYPT = "Decryption"; 9 | CSSM_KEYUSE_SIGN = "Signing"; 10 | CSSM_KEYUSE_VERIFY = "Verifying"; 11 | CSSM_KEYUSE_SIGN_RECOVER = "Sign recovery"; 12 | CSSM_KEYUSE_VERIFY_RECOVER = "Verification recovery"; 13 | CSSM_KEYUSE_WRAP = "Wrapping"; 14 | CSSM_KEYUSE_UNWRAP = "Unwrapping"; 15 | CSSM_KEYUSE_DERIVE = "Deriving"; 16 | 17 | CSSM_X509_DATAFORMAT_ENCODED = "Encoded"; 18 | CSSM_X509_DATAFORMAT_PARSED = "Parsed"; 19 | CSSM_X509_DATAFORMAT_PAIR = "Pair"; 20 | 21 | Unknown = "Unknown (%@)"; 22 | YES = "YES"; // It may be redundent having upper and lowercase versions 23 | yes = "yes"; // However, I've heard that some cultures find all uppercase 24 | NO = "NO"; // very offensive, or something to that effect. So, the 25 | no = "no"; // option is made here to change casing. -------------------------------------------------------------------------------- /Keychain/English.lproj/Keyblob Formats.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_KEYBLOB_FORMATs. */ 2 | 3 | /* The key is a combination of the numeric values of the keyblob type and keyblob format, separated by a hyphen. This is to get around the unfortunate design error of using overlapping enums for formats of different types. The numeric values understand are those in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the format, generally a single word. */ 5 | 6 | "0-0" = "None"; 7 | "0-1" = "RSA PKCS1 (v1.5)"; 8 | "0-2" = "RSA PKCS3 (v1.5)"; 9 | "0-3" = "Microsoft CAPI (v2)"; 10 | "0-4" = "PGP V"; 11 | "0-5" = "US Government FIPS 186 - DSS V"; 12 | "0-6" = "RSA Bsafe (v3)"; 13 | "0-9" = "CCA clear public key blob"; 14 | "0-10" = "RSA PKCS8 (v1.2)"; 15 | "0-11" = "SPKI Specification"; 16 | "0-12" = "Octet String"; 17 | 18 | "1-0" = "None"; 19 | "1-1" = "RSA PKCS8 (v1.2)"; 20 | "1-2" = "RSA PKCS7"; 21 | "1-3" = "Microsoft CAPI"; 22 | 23 | "2-0" = "Integer (e.g. handle)"; 24 | "2-1" = "String (e.g. label)"; 25 | "2-2" = "SPKI S-expression"; -------------------------------------------------------------------------------- /Keychain/English.lproj/Algorithm Modes.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_ENCRYPT_MODEs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the algorithm mode. */ 5 | 6 | 0 = "None"; 7 | 1 = "Custom"; 8 | 2 = "ECB"; 9 | 3 = "ECB Pad"; 10 | 4 = "CBC"; 11 | 5 = "CBC IV8"; 12 | 6 = "CBC Pad IV8"; 13 | 7 = "CFB"; 14 | 8 = "CFB IV8"; 15 | 9 = "CFB Pad IV8"; 16 | 10 = "OFB"; 17 | 11 = "OFB IV8"; 18 | 12 = "OFB Pad IV8"; 19 | 13 = "Counter"; 20 | 14 = "BC"; 21 | 15 = "PCBC"; 22 | 16 = "CBCC"; 23 | 17 = "OFBNLF"; 24 | 18 = "PBC"; 25 | 19 = "PFB"; 26 | 20 = "CBCPD"; 27 | 21 = "Public Key"; 28 | 22 = "Private Key"; 29 | 23 = "Shuffle"; 30 | 24 = "ECB 64"; 31 | 25 = "CBC 64"; 32 | 26 = "OFB 64"; 33 | 28 = "CFB 32"; 34 | 29 = "CFB 16"; 35 | 30 = "CFB 8"; 36 | 31 = "Wrap"; 37 | 32 = "Private Wrap"; 38 | 33 = "Relay X"; 39 | 34 = "ECB 128"; 40 | 35 = "ECB 96"; 41 | 36 = "CBC 128"; 42 | 37 = "OAEP HASH"; 43 | 38 = "PKCS1 EME V15"; 44 | 39 = "PKCS1 EME OAEP"; 45 | 40 = "PKCS1 EMSA V15"; 46 | 41 = "ISO 9796"; 47 | 42 = "X9 31"; -------------------------------------------------------------------------------- /Keychain/Hashcash.h: -------------------------------------------------------------------------------- 1 | // 2 | // Hashcash.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on 12/11/04. 6 | // Copyright 2004 Wade Tregaskis. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | #define kHashcashDefaultSeedLength 16 13 | #define kHashcashSuffixLengthLimit 128 14 | 15 | 16 | extern NSString *kDefaultHashcashStringFormat; 17 | 18 | 19 | @interface Hashcash : NSObject { 20 | unsigned int version; 21 | unsigned int bits; 22 | NSCalendarDate *date; 23 | NSString *resource; 24 | NSString *extensions; 25 | NSString *salt; 26 | NSString *suffix; 27 | } 28 | 29 | + (NSCharacterSet*)stampFieldCharacterSet; 30 | + (NSCharacterSet*)stampDateCharacterSet; 31 | 32 | + (Hashcash*)hashcashFromStamp:(NSString*)stamp; 33 | - (Hashcash*)initWithStamp:(NSString*)stamp; 34 | 35 | - (unsigned int)version; 36 | - (int)setVersion:(unsigned int)newVersion; 37 | 38 | - (unsigned int)bits; 39 | - (int)setBits:(unsigned int)newBits; 40 | 41 | - (NSCalendarDate*)date; 42 | - (int)setDate:(NSDate*)newDate usingDefaultFormat:(BOOL)useDefaultFormat; 43 | 44 | - (NSString*)resource; 45 | - (int)setResource:(NSString*)newResource; 46 | 47 | - (NSString*)extensions; 48 | - (int)setExtensions:(NSString*)newExtensions; 49 | 50 | - (NSString*)salt; 51 | - (int)setSalt:(NSString*)newSalt; 52 | 53 | - (NSString*)suffix; 54 | - (int)setSuffix:(NSString*)newSuffix; 55 | - (int)findSuffix; 56 | 57 | - (NSString*)stamp; 58 | 59 | - (BOOL)valid; 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeExtensions 11 | 12 | delicious 13 | 14 | CFBundleTypeIconFile 15 | delicious 16 | CFBundleTypeName 17 | Del.icio.us Bookmark 18 | CFBundleTypeOSTypes 19 | 20 | DELi 21 | 22 | CFBundleTypeRole 23 | Editor 24 | LSItemContentTypes 25 | 26 | org.ianhenderson.delicious.bookmark 27 | 28 | LSTypeIsPackage 29 | 30 | NSPersistentStoreTypeKey 31 | XML 32 | 33 | 34 | CFBundleExecutable 35 | delimport 36 | CFBundleIconFile 37 | delicious 38 | CFBundleIdentifier 39 | org.ianhenderson.delimport 40 | CFBundleInfoDictionaryVersion 41 | 6.0 42 | CFBundlePackageType 43 | APPL 44 | CFBundleSignature 45 | DeLi 46 | CFBundleVersion 47 | 0.3 48 | LSUIElement 49 | 1 50 | NSMainNibFile 51 | MainMenu 52 | NSPrincipalClass 53 | NSApplication 54 | 55 | 56 | -------------------------------------------------------------------------------- /Keychain/MultiThreading.h: -------------------------------------------------------------------------------- 1 | // 2 | // MultiThreading.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Mon May 26 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | 16 | 17 | extern NSLock * keychainCachedObjectLock; 18 | 19 | 20 | @interface KeychainThreadController : NSObject {} 21 | 22 | + (KeychainThreadController*)defaultController; 23 | 24 | - (KeychainThreadController*)init; 25 | 26 | - (void)activateThreadSafety; 27 | - (void)deactivateThreadSafety; 28 | 29 | @end -------------------------------------------------------------------------------- /Keychain/CertificateExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // CertificateExtensions.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Mon Jul 12 2004. 6 | // 7 | // Copyright (c) 2004, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | 15 | #import 16 | #import 17 | 18 | 19 | @interface AlternateName : Extension {} 20 | 21 | + (Extension*)alternateNameWithNameList:(NameList*)list; 22 | 23 | - (Extension*)initWithNameList:(NameList*)list; 24 | 25 | @end 26 | 27 | 28 | NameList* subjectAlternateName(CSSM_DATA *fieldValue); 29 | NameList* issuerAlternateName(CSSM_DATA *fieldValue); 30 | -------------------------------------------------------------------------------- /Keychain/Usage.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\mac\ansicpg10000\cocoartf102 2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \margl1440\margr1440\vieww9000\viewh9000\viewkind0 5 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural 6 | 7 | \f0\fs36 \cf0 Keychain Framework Usage 8 | \fs24 \ 9 | \ 10 | 11 | \fs32 Building 12 | \fs24 \ 13 | \ 14 | The framework can be configured in several ways at compile time, to produce an executable that best suits your particular needs.\ 15 | The first flags of interest are those related to logging. The framework contains a lot of informational and debugging output, which can take significant space both on disk and in memory. By default everything is included in development builds (those where NDEBUG is not defined) and only non-debug output is included in deployment builds (those where NDEBUG is defined). You shouldn't need to enter this flag manually.\ 16 | If you want even less output you can also define any of the NO_STANDARD_OUTPUT, NO_ERROR_OUTPUT and NO_CONSOLE_OUTPUT flags. These selectively turn off each type of output. Console output is typically used throughout the framework for basic error messages, which describe the problem in layman's terms and provide only an error code for debugging. You should generally leave these in - it will help you and your users identify the exact failing. You can then later have your user substitute a debug version of the framework in order to gather more information.\ 17 | Standard & error output are not usually used by the framework explicitly, as there is no guarantee they will be user-visible (i.e. as in the case of a GUI program). You may wish to use them in your own code.\ 18 | \ 19 | In addition, the various outputs can be rerouted to alternative locations. For example, if STD_ERR_TO_CONSOLE is defined, output that usually goes to standard error will instead go to the console. There are several such flags - see the Logging header file (or it's generated HeaderDoc documentation) for more information.} -------------------------------------------------------------------------------- /Keychain/Readme.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\mac\ansicpg10000\cocoartf102 2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww12900\viewh8760\viewkind0 5 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural 6 | 7 | \f0\fs24 \cf0 The Keychain framework is provided as-is, with no warrantee expressed or implied, etc etc. Standard BS disclaimer.\ 8 | \ 9 | More importantly, and from a human now:\ 10 | \ 11 | * Please send in bug reports. Yes, the whole thing's probably busting at the seams with them, but unfortunately there is a very wide range of uses, and I simply cannot test or even anticipate all of them. No matter how obvious it seems, if it's not listed as a known issue in the release notes, I probably don't know about it. Bug reports should go to or the SourceForge page at (in the bugs section, of course).\ 12 | \ 13 | * This framework is considered alpha. The interfaces are not finalized, and now and again I do change things around significantly. All in the name of progress. If you use it now, you do run the risk of having your code break in a later release. However, nearly all the changes are superficial and can easily be resolved by running a quick search & replace on your code. So don't fear too much. But don't say you weren't warned, either.\ 14 | \ 15 | * Please contribute. I simply cannot write everything. There is so much functionality I would love to add, but I can only do so much, and so I only do what I need personally. If you need something else, by all means add it. Once code is contributed I'll take any necessary responsibility for keeping it up to date and so forth, so don't be afraid to throw something at me, even if you don't want to know about it any further.\ 16 | \ 17 | * Refer to the 'Usage.rtf' file for information on how to include the framework into your applications, as well as information on how to build it with various options enabled or disabled.} -------------------------------------------------------------------------------- /Keychain/CertificateExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // CertificateExtensions.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Mon Jul 12 2004. 6 | // 7 | // Copyright (c) 2004, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "CertificateExtensions.h" 15 | 16 | 17 | /* Extension structure */ 18 | /*typedef struct cssm_x509_extension { 19 | CSSM_OID extnId; 20 | CSSM_BOOL critical; 21 | CSSM_X509EXT_DATA_FORMAT format; 22 | union cssm_x509ext_value { 23 | CSSM_X509EXT_TAGandVALUE *tagAndValue; 24 | void *parsedValue; 25 | CSSM_X509EXT_PAIR *valuePair; 26 | } value; 27 | CSSM_DATA BERvalue; 28 | } CSSM_X509_EXTENSION, *CSSM_X509_EXTENSION_PTR; */ 29 | 30 | 31 | NameList* subjectAlternateName(CSSM_DATA *fieldValue) { 32 | //CSSM_X509_EXTENSION *ext = (CSSM_X509_EXTENSION*)fieldValue->Data; 33 | 34 | return nil; // FLAG - to be completed 35 | } 36 | 37 | NameList* issuerAlternateName(CSSM_DATA *fieldValue) { 38 | return subjectAlternateName(fieldValue); 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # delimport-pinboard 2 | 3 | Index your [Pinboard](http://pinboard.in) bookmarks using [Spotlight](http://www.apple.com/macosx/what-is-macosx/spotlight.html) 4 | on Mac OS X. Updates every half-hour. Includes url, title, description, and tags. 5 | 6 | I've been heavily invested in [Delicious](http://delicious.com) as a bookmarking service for many years. 7 | However, after learning about Delicious' [sunsetting](https://twitter.com/waxpancake/status/15483488237002752), 8 | I've decided to join the ranks of the [Great Delicious Exodus](https://twitter.com/PinboardIN/status/20323781167816704) 9 | and sign up for an account with [Pinboard](http://pinboard.in). 10 | 11 | This is a fork of the awesome [delimport](http://ianhenderson.org/delimport.html), which automatically indexes 12 | Delicious bookmarks and makes them available via Spotlight and Spotlight-powered tools (e.g. 13 | [Alfred](http://alfredapp.com)) on Mac OS X. This fork indexes your Pinboard bookmarks instead. 14 | 15 | 16 | ## Building from Source 17 | 18 | Ian's code requires the _Mac OS X 10.4u SDK_. I had to uninstall Xcode 3.2.x and reinstall Xcode 3.1.4 to 19 | get the 10.4u SDK so I could compile. I've documented my own process in the post: 20 | [Import Delicious/Pinboard Bookmarks Into Spotlight for Mac OS X](http://blog.ryanparman.com/2011/01/01/import-deliciouspinboard-bookmarks-into-spotlight-for-mac-os-x/). 21 | 22 | Assuming you have the Mac OS X 10.4u SDK installed, it should simply be: 23 | 24 | git clone git://github.com/skyzyx/delimport-pinboard.git 25 | cd delimport-pinboard 26 | open delimport.xcodeproj 27 | 28 | Then click the _Build_ button at the top of Xcode. 29 | 30 | 31 | ## Known Issues 32 | 33 | * Pinboard tags don't seem to be indexed. I need to poke around in Ian's code a little more. 34 | 35 | 36 | ## Contributing 37 | 38 | I don't know the first thing about Objective-C or the Cocoa frameworks. I'm just good at poking around 39 | in the code and replacing strings here and there. I don't provide support, because I wouldn't have any 40 | answers for you anyway. Let me know if you know Objective-C and want to contribute. 41 | 42 | 43 | ## License and Copyright 44 | 45 | This software is copyright (c) 2007 Ian Henderson. 46 | 47 | There is no license as far as I can find, so I'm putting myself on the line by redistributing this code. 48 | I've contacted Ian and asked what the license is, but he hasn't responded up to this point. I hope he's 49 | okay with this. Ian, if you're not, please let me know. 50 | -------------------------------------------------------------------------------- /spotlight_interface/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 14 | 15 | UTExportedTypeDeclarations 16 | 17 | 18 | UTTypeIdentifier 19 | org.ianhenderson.delicious.bookmark 20 | UTTypeReferenceURL 21 | http://del.icio.us/ 22 | UTTypeDescription 23 | del.icio.us Bookmark 24 | UTTypeConformsTo 25 | 26 | com.apple.safari.bookmark 27 | 28 | UTTypeTagSpecification 29 | 30 | com.apple.ostype 31 | DELi 32 | public.filename-extension 33 | 34 | delicious 35 | 36 | 37 | 38 | 39 | 40 | CFBundleDevelopmentRegion 41 | English 42 | CFBundleDocumentTypes 43 | 44 | 45 | CFBundleTypeRole 46 | MDImporter 47 | LSItemContentTypes 48 | 49 | org.ianhenderson.delicious.bookmark 50 | 51 | 52 | 53 | CFBundleExecutable 54 | del.icio.us Spotlight Interface 55 | CFBundleIconFile 56 | 57 | CFBundleIdentifier 58 | org.ianhenderson.delicious 59 | CFBundleInfoDictionaryVersion 60 | 6.0 61 | CFBundleVersion 62 | 1.0 63 | CFPlugInDynamicRegisterFunction 64 | 65 | CFPlugInDynamicRegistration 66 | NO 67 | CFPlugInFactories 68 | 69 | E3F78F66-0992-4466-A3B8-4E8C100B246D 70 | MetadataImporterPluginFactory 71 | 72 | CFPlugInTypes 73 | 74 | 8B08C4BF-415B-11D8-B3F9-0003936726FC 75 | 76 | E3F78F66-0992-4466-A3B8-4E8C100B246D 77 | 78 | 79 | CFPlugInUnloadFunction 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Keychain/English.lproj/Algorithms.strings: -------------------------------------------------------------------------------- 1 | /* This file contains names for CSSM_ALGORITHMSs. */ 2 | 3 | /* The key is the numeric value as defined in cssmtype.h in Apple's Security framework. Last updated for 10.3.9. */ 4 | /* The value is human-readable name for the algorithm. */ 5 | 6 | 0 = "None"; 7 | 1 = "Custom"; 8 | 2 = "DH"; 9 | 3 = "PH"; 10 | 4 = "KEA"; 11 | 5 = "MD2"; 12 | 6 = "MD4"; 13 | 7 = "MD5"; 14 | 8 = "SHA1"; 15 | 9 = "NHASH"; 16 | 10 = "HAVAL"; 17 | 11 = "RIPEMD"; 18 | 12 = "IBCHASH"; 19 | 13 = "RIPEMAC"; 20 | 14 = "DES"; 21 | 15 = "DESX"; 22 | 16 = "RDES"; 23 | 17 = "3-Key TripleDES EDE"; 24 | 18 = "2-Key TripleDES EDE"; 25 | 19 = "1-Key TripleDES EEE"; 26 | 20 = "3-Key TripleDES EEE"; 27 | 21 = "2-Key TripleDES EEE"; 28 | 22 = "IDEA"; 29 | 23 = "RC2"; 30 | 24 = "RC5"; 31 | 25 = "RC4"; 32 | 26 = "SEAL"; 33 | 27 = "CAST"; 34 | 28 = "Blowfish"; 35 | 29 = "Skipjack"; 36 | 30 = "Lucifer"; 37 | 31 = "Madryga"; 38 | 32 = "FEAL"; 39 | 33 = "REDOC"; 40 | 34 = "REDOC3"; 41 | 35 = "LOKI"; 42 | 36 = "KHUFU"; 43 | 37 = "KHAFRE"; 44 | 38 = "MMB"; 45 | 39 = "GOST"; 46 | 40 = "SAFER"; 47 | 41 = "CRAB"; 48 | 42 = "RSA"; 49 | 43 = "DSA"; 50 | 44 = "MD5 with RSA"; 51 | 45 = "MD2 with RSA"; 52 | 46 = "El Gamal"; 53 | 47 = "MD2 Random"; 54 | 48 = "MD5 Random"; 55 | 49 = "SHA Random"; 56 | 50 = "DES Random"; 57 | 51 = "SHA1 with RSA"; 58 | 52 = "CDMF"; 59 | 53 = "CAST3"; 60 | 54 = "CAST5"; 61 | 55 = "Generic Secret"; 62 | 56 = "Concat Base and Key"; 63 | 57 = "Concat Key and Base"; 64 | 58 = "Concat Base and Data"; 65 | 59 = "Concat Data and Base"; 66 | 60 = "XOR Base and Data"; 67 | 61 = "Extract from Key"; 68 | 62 = "SSL3 Pre-Master Gen"; 69 | 63 = "SSL3 Master Derive"; 70 | 64 = "SSL3 Key & MAC Derive"; 71 | 65 = "SSL3 MD5-MAC"; 72 | 66 = "SSL3 SHA1-MAC"; 73 | 67 = "PKCS5 PBKDF1 MD5"; 74 | 68 = "PKCS5 PBKDF1 MD2"; 75 | 69 = "PKCS5 PBKDF1 SHA1"; 76 | 70 = "WrapLynks"; 77 | 71 = "WrapSET OAEP"; 78 | 72 = "BATON"; 79 | 73 = "ECDSA"; 80 | 74 = "Mayfly"; 81 | 75 = "Juniper"; 82 | 76 = "Fasthash"; 83 | 77 = "TripleDES"; 84 | 78 = "SSL3 MD5"; 85 | 79 = "SSL3 SHA1"; 86 | 80 = "Fortezza Timestamp"; 87 | 81 = "SHA1 with DSA"; 88 | 82 = "SHA1 with ECDSA"; 89 | 83 = "DSA Bsafe"; 90 | 84 = "ECDH"; 91 | 85 = "ECMQV"; 92 | 86 = "PKCS12 SHA1 PBE"; 93 | 87 = "ECNRA"; 94 | 88 = "SHA1 with ECNRA"; 95 | 89 = "ECES"; 96 | 90 = "ECAES"; 97 | 91 = "SHA1 HMAC"; 98 | 92 = "FIPS 186 Random"; 99 | 93 = "ECC"; 100 | 94 = "MQV"; 101 | 95 = "NRA"; 102 | 96 = "Intel Platform Random"; 103 | 97 = "UTC"; 104 | 98 = "HAVAL3"; 105 | 99 = "HACAL4"; 106 | 100 = "HAVAL5"; 107 | 101 = "TIGER"; 108 | 102 = ="MD5 HMAC"; 109 | 103 = "PKCS5 PBKDF2"; 110 | 104 = "Running Counter"; -------------------------------------------------------------------------------- /Keychain/KeychainUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainUtils.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed May 14 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import "CSSMDefaults.h" 17 | 18 | 19 | char* generateRandomData(uint32 lengthInBytes, CSSM_ALGORITHMS algorithm, const char *seed, unsigned int seedLength); 20 | NSData* generateRandomNSData(uint32 lengthInBytes, CSSM_ALGORITHMS algorithm, NSData *seed); 21 | 22 | #define generateGenericRandomData(lengthInBytes) generateRandomData(lengthInBytes, DEFAULT_RANDOM_ALGORITHM, NULL, 0) 23 | #define generateParticularRandomData(lengthInBytes, algorithm) generateRandomData(lengthInBytes, algorithm, NULL, 0) 24 | #define generateSeededRandomData(lengthInBytes, seed, seedLength) generateRandomData(lengthInBytes, DEFAULT_RANDOM_ALGORITHM, seed, seedLength) 25 | 26 | #define generateGenericRandomNSData(lengthInBytes) generateRandomNSData(lengthInBytes, DEFAULT_RANDOM_ALGORITHM, nil) 27 | #define generateParticularRandomNSData(lengthInBytes, algorithm) generateRandomNSData(lengthInBytes, algorithm, nil) 28 | #define generateSeededRandomNSData(lengthInBytes, seed) generateRandomNSData(lengthInBytes, DEFAULT_RANDOM_ALGORITHM, seed) 29 | -------------------------------------------------------------------------------- /Keychain/CSSMErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMErrors.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Thu May 29 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | 16 | #import 17 | 18 | 19 | /*! @function CSSMErrorAsString 20 | @abstract Returns a human-readable name of a given error code, possibly with a short (one-line) description of the error. 21 | @discussion When displaying errors to the user you should always provide both a code and the name of the error - the code can be easily copied down for reporting back to you, the developer, while the name may provide some aid to the user in determining what the problem is; e.g. if it is "CL CRL already signed", they may be able to deduce that they are trying to re-sign an existing CRL, instead of a new one, or something similar. 22 | 23 | This function looks up the strings in an appropriate strings table, and as such will return localised names. At time of writing the only localisation supported is English. 24 | @param error The CSSM error code. 25 | @result Returns a human-readable string containing at least the name of the error code, and possibly also a very brief description of the error. Returns "Unknown" for any unknown error codes (suitably localised, of course). */ 26 | 27 | NSString* CSSMErrorAsString(CSSM_RETURN error); 28 | -------------------------------------------------------------------------------- /Keychain/Policy.h: -------------------------------------------------------------------------------- 1 | // 2 | // Policy.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | @interface Policy : NSCachedObject { 20 | SecPolicyRef policy; 21 | int error; 22 | } 23 | 24 | + (Policy*)policyWithPolicyRef:(SecPolicyRef)poli; 25 | 26 | - (Policy*)initWithPolicyRef:(SecPolicyRef)poli; 27 | 28 | /*! @method init 29 | @abstract Reject initialiser. 30 | @discussion You cannot initialise a Policy using "init" - use one of the other initialisation methods. 31 | @result This method always releases the receiver and returns nil. */ 32 | 33 | - (Policy*)init; 34 | 35 | - (NSData*)objectIdentifier; 36 | - (NSData*)data; 37 | 38 | /*! @method lastError 39 | @abstract Returns the last error that occured for the receiver. 40 | @discussion The set of error codes encompasses those returned by Sec* functions - refer to the Security framework documentation for a list. At present there are no other error codes defined for Access instances. 41 | 42 | Please note that this error code is local to the receiver only, and not any sort of shared global value. 43 | @result The last error that occured, or zero if the last operation was successful. */ 44 | 45 | - (int)lastError; 46 | - (SecPolicyRef)policyRef; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Keychain/NSDataAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDataAdditions.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed May 07 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | NSData* cononicalFormOfExecutable(NSString *path); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | @interface NSData (Keychain) 30 | 31 | - (NSData*)encryptedDataUsingKey:(Key*)key; 32 | - (NSData*)decryptedDataUsingKey:(Key*)key; 33 | 34 | - (NSData*)encryptedDataUsingKey:(Key*)key mode:(CSSM_ENCRYPT_MODE)mode padding:(CSSM_PADDING)padding; 35 | - (NSData*)decryptedDataUsingKey:(Key*)key mode:(CSSM_ENCRYPT_MODE)mode padding:(CSSM_PADDING)padding; 36 | 37 | - (NSData*)MACUsingKey:(Key*)key; 38 | - (BOOL)verifyUsingKey:(Key*)key MAC:(NSData*)MAC; 39 | 40 | - (NSData*)signatureUsingKey:(Key*)key; 41 | - (NSData*)signatureUsingKey:(Key*)key digest:(CSSM_ALGORITHMS)algorithm; 42 | - (NSData*)digestSignatureUsingKey:(Key*)key digest:(CSSM_ALGORITHMS)algorithm; 43 | 44 | - (BOOL)verifySignature:(NSData*)signature usingKey:(Key*)key; 45 | - (BOOL)verifySignature:(NSData*)signature usingKey:(Key*)key digest:(CSSM_ALGORITHMS)algorithm; 46 | - (BOOL)verifyDigestSignature:(NSData*)signature usingKey:(Key*)key digest:(CSSM_ALGORITHMS)algorithm; 47 | 48 | - (MutableKey*)key; 49 | 50 | - (NSData*)digestUsingAlgorithm:(CSSM_ALGORITHMS)algorithm; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Keychain/MultiThreading.m: -------------------------------------------------------------------------------- 1 | // 2 | // MultiThreading.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Mon May 26 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "MultiThreading.h" 15 | 16 | //#import "Logging.h" 17 | 18 | 19 | NSLock *keychainCachedObjectLock = nil; 20 | 21 | 22 | @implementation KeychainThreadController 23 | 24 | + (KeychainThreadController*)defaultController { 25 | static KeychainThreadController *controller; 26 | 27 | if (!controller) { 28 | controller = [[KeychainThreadController alloc] init]; 29 | } 30 | 31 | return controller; 32 | } 33 | 34 | - (KeychainThreadController*)init { 35 | return (self = [super init]); 36 | } 37 | 38 | - (void)taskNowMultiThreaded:(NSNotification*)event { 39 | //PDEBUG(@"Keychain framework operating in thread-safe mode.\n"); 40 | 41 | if (!keychainCachedObjectLock) { 42 | keychainCachedObjectLock = [[NSLock alloc] init]; 43 | } 44 | } 45 | 46 | - (void)activateThreadSafety { 47 | //PDEBUG(@"Keychain framework told to be thread safe if necessary.\n"); 48 | 49 | if ([NSThread isMultiThreaded]) { 50 | [self taskNowMultiThreaded:nil]; 51 | } else { 52 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskNowMultiThreaded:) name:NSWillBecomeMultiThreadedNotification object:nil]; 53 | } 54 | } 55 | 56 | - (void)deactivateThreadSafety { 57 | [[NSNotificationCenter defaultCenter] removeObserver:[KeychainThreadController defaultController]]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Keychain/License.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\mac\ansicpg10000\cocoartf102 2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww13480\viewh12340\viewkind0 5 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural 6 | 7 | \f0\fs24 \cf0 The Keychain framework and all the code it contains are now distributed under the standard BSD license. As those who've played with it previously will know, I had original posted it with no copyright info and all rights reserved, making it unusable by anyone else. This was of course not my intention - I've just been lazy about deciding upon a license and copy-pasting it into the source files. :)\ 8 | \ 9 | But now I have, and you can read a copy of it at the end of this file. I decided to go with the BSD license after talking to a few people on the Cocoa-dev mailing list about licenses, in which I proposed a "pro-competition" license (i.e. certain evil monopolies can't even look at the code, let alone steal it). While I still stand by that ethical point of view, it doesn't look like I could easily enforce it in a license without causing headaches for other non-evil users. So I've dropped it, with the reasoning that if said evil monopoly actually implements ObjC with Foundation support on that other platform - as they would have to in order to use this code - well, they can just have the code then. :)\ 10 | \ 11 | So, sorry for the delay in the licensing business. This license applies to all previous releases, too, so if you're already using them you can sleep better tonight. ;)\ 12 | \ 13 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved.\ 14 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ 15 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ 16 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ 17 | // * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.} -------------------------------------------------------------------------------- /DIFileController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DIFileController.m 3 | // delimport 4 | // 5 | // Created by Ian Henderson on 28.04.05. 6 | // Copyright 2005 Ian Henderson. All rights reserved. 7 | // 8 | 9 | #import "DIFileController.h" 10 | 11 | 12 | @implementation DIFileController 13 | 14 | - (NSString *)cachePath 15 | { 16 | NSString *cachePath = [@"~/Library/Caches/Metadata/delimport" stringByExpandingTildeInPath]; 17 | NSFileManager *fileManager = [NSFileManager defaultManager]; 18 | BOOL isDir; 19 | 20 | if ([fileManager fileExistsAtPath:cachePath isDirectory:&isDir]) { 21 | if (isDir) { 22 | return cachePath; 23 | } 24 | } else if ([fileManager createDirectoryAtPath:cachePath attributes:nil]) { 25 | return cachePath; 26 | } 27 | 28 | return nil; 29 | } 30 | 31 | - (void)saveDictionary:(NSDictionary *)dictionary 32 | { 33 | NSMutableDictionary *mutable = [dictionary mutableCopy]; 34 | NSNumber *osType = [NSNumber numberWithUnsignedLong:'DELi']; 35 | NSString *path = [[[self cachePath] stringByAppendingPathComponent:[mutable objectForKey:@"hash"]] stringByAppendingPathExtension:@"delicious"]; 36 | if (!path) { 37 | return; 38 | } 39 | [mutable removeObjectForKey:@"hash"]; 40 | [mutable writeToFile:path atomically:YES]; 41 | 42 | [[NSFileManager defaultManager] changeFileAttributes:[NSDictionary dictionaryWithObject:osType forKey:NSFileHFSTypeCode] atPath:path]; 43 | /* set creation date do delicious date 44 | setting the modification date might be more useful, but would be 'wrong' as we don't know when the bookmark was last edited. 45 | investigate setting the last used date as well? This would put bookmarks in their correct order in Spotlight results. 46 | */ 47 | NSDate * date = [mutable objectForKey:@"time"]; 48 | if (date) { 49 | [[NSFileManager defaultManager] changeFileAttributes:[NSDictionary dictionaryWithObject:date forKey:NSFileCreationDate] atPath:path]; 50 | } 51 | [mutable release]; 52 | } 53 | 54 | - (void)deleteDictionary:(NSDictionary *)dictionary 55 | { 56 | NSString *path = [[[self cachePath] stringByAppendingPathComponent:[dictionary objectForKey:@"hash"]] stringByAppendingPathExtension:@"delicious"]; 57 | if (!path) { 58 | return; 59 | } 60 | [[NSFileManager defaultManager] removeFileAtPath:path handler:nil]; 61 | } 62 | 63 | - (void)saveDictionaries:(NSSet *)dictionaries 64 | { 65 | NSEnumerator *dictEnumerator = [dictionaries objectEnumerator]; 66 | NSDictionary *dictionary; 67 | while (dictionary = [dictEnumerator nextObject]) { 68 | [self saveDictionary:dictionary]; 69 | } 70 | } 71 | 72 | - (void)deleteDictionaries:(NSSet *)dictionaries 73 | { 74 | NSEnumerator *dictEnumerator = [dictionaries objectEnumerator]; 75 | NSDictionary *dictionary; 76 | while (dictionary = [dictEnumerator nextObject]) { 77 | [self deleteDictionary:dictionary]; 78 | } 79 | } 80 | 81 | - (BOOL)openFile:(NSString *)filename 82 | { 83 | NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filename]; 84 | if (!dict) { 85 | return NO; 86 | } 87 | NSString *href = [dict objectForKey:@"href"]; 88 | if (!href) { 89 | return NO; 90 | } 91 | return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:href]]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /Keychain/Policy.m: -------------------------------------------------------------------------------- 1 | // 2 | // Policy.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "Policy.h" 15 | 16 | #import 17 | 18 | 19 | @implementation Policy 20 | 21 | + (Policy*)policyWithPolicyRef:(SecPolicyRef)poli { 22 | return [[[[self class] alloc] initWithPolicyRef:poli] autorelease]; 23 | } 24 | 25 | - (Policy*)initWithPolicyRef:(SecPolicyRef)poli { 26 | Policy *existingObject; 27 | 28 | if (poli) { 29 | existingObject = [[self class] instanceWithKey:(id)poli from:@selector(policyRef) simpleKey:NO]; 30 | 31 | if (existingObject) { 32 | [self release]; 33 | 34 | return [existingObject retain]; 35 | } else { 36 | if (self = [super init]) { 37 | CFRetain(poli); 38 | policy = poli; 39 | } 40 | 41 | return self; 42 | } 43 | } else { 44 | [self release]; 45 | 46 | return nil; 47 | } 48 | } 49 | 50 | - (Policy*)init { 51 | [self release]; 52 | return nil; 53 | } 54 | 55 | - (NSData*)objectIdentifier { 56 | CSSM_OID result; 57 | 58 | error = SecPolicyGetOID(policy, &result); 59 | 60 | if (error == 0) { 61 | return NSDataFromData(&result); 62 | } else { 63 | return nil; 64 | } 65 | } 66 | 67 | - (NSData*)data { 68 | CSSM_DATA result; 69 | 70 | error = SecPolicyGetValue(policy, &result); 71 | 72 | if (error == 0) { 73 | return NSDataFromData(&result); 74 | } else { 75 | return nil; 76 | } 77 | } 78 | 79 | - (int)lastError { 80 | return error; 81 | } 82 | 83 | - (SecPolicyRef)policyRef { 84 | return policy; 85 | } 86 | 87 | - (void)dealloc { 88 | if (policy) { 89 | CFRelease(policy); 90 | } 91 | 92 | [super dealloc]; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /spotlight_interface/GetMetadataForFile.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* ----------------------------------------------------------------------------- 6 | Step 1 7 | Set the UTI types the importer supports 8 | 9 | Modify the CFBundleDocumentTypes entry in Info.plist to contain 10 | an array of Uniform Type Identifiers (UTI) for the LSItemContentTypes 11 | that your importer can handle 12 | 13 | ----------------------------------------------------------------------------- */ 14 | 15 | /* ----------------------------------------------------------------------------- 16 | Step 2 17 | Implement the GetMetadataForFile function 18 | 19 | Implement the GetMetadataForFile function below to scrape the relevant 20 | metadata from your document and return it as a CFDictionary using standard keys 21 | (defined in MDItem.h) whenever possible. 22 | ----------------------------------------------------------------------------- */ 23 | 24 | /* ----------------------------------------------------------------------------- 25 | Step 3 (optional) 26 | If you have defined new attributes, update the schema.xml file 27 | 28 | Edit the schema.xml file to include the metadata keys that your importer returns. 29 | Add them to the and elements. 30 | 31 | Add any custom types that your importer requires to the element 32 | 33 | 34 | 35 | ----------------------------------------------------------------------------- */ 36 | 37 | 38 | 39 | /* ----------------------------------------------------------------------------- 40 | Get metadata attributes from file 41 | 42 | This function's job is to extract useful information your file format supports 43 | and return it as a dictionary 44 | ----------------------------------------------------------------------------- */ 45 | 46 | Boolean GetMetadataForFile(void* thisInterface, 47 | CFMutableDictionaryRef attrs, 48 | CFStringRef contentTypeUTI, 49 | CFStringRef pathToFile) 50 | { 51 | NSDictionary *dictionary; 52 | NSMutableDictionary *attributes = attrs; 53 | NSAutoreleasePool *pool; 54 | pool = [[NSAutoreleasePool alloc] init]; 55 | 56 | dictionary = [[NSDictionary alloc] initWithContentsOfFile:(NSString *)pathToFile]; 57 | if (!dictionary) { 58 | [pool release]; 59 | return NO; 60 | } 61 | [attributes setObject:[dictionary objectForKey:@"description"] forKey:(NSString *)kMDItemDisplayName]; 62 | [attributes setObject:[dictionary objectForKey:@"tag"] forKey:(NSString *)kMDItemKeywords]; 63 | if ([dictionary objectForKey:@"extended"]) { 64 | [attributes setObject:[dictionary objectForKey:@"extended"] forKey:(NSString *)kMDItemDescription]; 65 | } else { 66 | [attributes setObject:@"" forKey:(NSString *)kMDItemDescription]; 67 | } 68 | [attributes setObject:[dictionary objectForKey:@"time"] forKey:(NSString *)kMDItemContentCreationDate]; 69 | [attributes setObject:[dictionary objectForKey:@"time"] forKey:(NSString *)kMDItemContentModificationDate]; 70 | [attributes setObject:@"Del.icio.us Bookmark" forKey:(NSString *)kMDItemKind]; 71 | [attributes setObject:[dictionary objectForKey:@"href"] forKey:@"kMDItemURL"]; 72 | 73 | [pool release]; 74 | return YES; 75 | } 76 | -------------------------------------------------------------------------------- /Keychain/TrustedApplication.h: -------------------------------------------------------------------------------- 1 | // 2 | // TrustedApplication.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | @interface TrustedApplication : NSCachedObject { 20 | SecTrustedApplicationRef trustedApplication; 21 | int error; 22 | } 23 | 24 | + (TrustedApplication*)trustedApplicationWithPath:(NSString*)path; 25 | + (TrustedApplication*)trustedApplicationWithTrustedApplicationRef:(SecTrustedApplicationRef)trustedApp; 26 | 27 | - (TrustedApplication*)initWithPath:(NSString*)path; 28 | - (TrustedApplication*)initWithTrustedApplicationRef:(SecTrustedApplicationRef)trustedApp; 29 | 30 | /*! @method init 31 | @abstract Initialises the receiver as a TrustedApplication for the current application. 32 | @discussion Note that this is the same as calling initWithPath: and passing nil as the path parameter. As a consequence, it also will always initialise a new instance, even if an existing instance for the same path already exists. 33 | @result Returns the receiver if successful, otherwise releases the receiver and returns nil. */ 34 | 35 | - (TrustedApplication*)init; 36 | 37 | - (void)setData:(NSData*)data; 38 | - (NSData*)data; 39 | 40 | /*! @method lastError 41 | @abstract Returns the last error that occured for the receiver. 42 | @discussion The set of error codes encompasses those returned by Sec* functions - refer to the Security framework documentation for a list. At present there are no other error codes defined for Access instances. 43 | 44 | Please note that this error code is local to the receiver only, and not any sort of shared global value. 45 | @result The last error that occured, or zero if the last operation was successful. */ 46 | 47 | - (int)lastError; 48 | - (SecTrustedApplicationRef)trustedApplicationRef; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Keychain/CertificateBundle.h: -------------------------------------------------------------------------------- 1 | // 2 | // CertificateBundle.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sat Feb 01 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | @interface CertificateBundle : NSObject { 20 | CSSM_CERT_BUNDLE_PTR bundle; 21 | BOOL releaseWhenDone; 22 | int error; 23 | } 24 | 25 | + (CertificateBundle*)certificateBundleWithCertificates:(NSArray*)certs; 26 | + (CertificateBundle*)certificateBundleOfType:(CSSM_CERT_BUNDLE_TYPE)type withEncoding:(CSSM_CERT_BUNDLE_ENCODING)encoding withCertificates:(NSArray*)certs; 27 | + (CertificateBundle*)certificateBundleWithBundle:(CSSM_CERT_BUNDLE_PTR)bun; 28 | + (CertificateBundle*)certificateBundleWithBundle:(CSSM_CERT_BUNDLE_PTR)bun releasingWhenDone:(BOOL)release; 29 | 30 | - (CertificateBundle*)initWithCertificates:(NSArray*)certs; 31 | - (CertificateBundle*)initWithType:(CSSM_CERT_BUNDLE_TYPE)type withEncoding:(CSSM_CERT_BUNDLE_ENCODING)encoding withCertificates:(NSArray*)certs; 32 | - (CertificateBundle*)initWithBundle:(CSSM_CERT_BUNDLE_PTR)bun; 33 | - (CertificateBundle*)initWithBundle:(CSSM_CERT_BUNDLE_PTR)bun releasingWhenDone:(BOOL)release; 34 | 35 | /*! @method init: 36 | @abstract Reject initialiser. 37 | @discussion You cannot initialise a CertificateBundle using "init" - use one of the other initialisation methods. 38 | @result This method always releases the receiver and returns nil. */ 39 | 40 | - (CertificateBundle*)init; 41 | 42 | - (CSSM_CERT_BUNDLE_TYPE)type; 43 | - (BOOL)typeIsCustom; 44 | - (BOOL)typeIsPKCS7; 45 | - (BOOL)typeIsPKCS7Enveloped; 46 | - (BOOL)typeIsPKCS12; 47 | - (BOOL)typeIsPFX; 48 | - (BOOL)typeIsSPKI; 49 | - (BOOL)typeIsPGP; 50 | - (BOOL)typeIsUnknown; 51 | 52 | - (CSSM_CERT_BUNDLE_ENCODING)encoding; 53 | - (BOOL)encodingIsCustom; 54 | - (BOOL)encodingIsBER; 55 | - (BOOL)encodingIsDER; 56 | - (BOOL)encodingIsSEXPR; 57 | - (BOOL)encodingIsPGP; 58 | - (BOOL)encodingIsUnknown; 59 | 60 | - (int)lastError; 61 | - (CSSM_CERT_BUNDLE_PTR)bundle; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Keychain/Trust.h: -------------------------------------------------------------------------------- 1 | // 2 | // Trust.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed Feb 05 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | 20 | 21 | @interface Trust : NSCachedObject { 22 | SecTrustRef trust; 23 | SecTrustResultType lastEval; 24 | int error; 25 | } 26 | 27 | + (SecTrustUserSetting)userTrustForCeritifcate:(Certificate*)cert policy:(Policy*)pol; 28 | + (void)setUserTrustForCertificate:(Certificate*)cert policy:(Policy*)pol trust:(SecTrustUserSetting)tru; 29 | 30 | + (Trust*)trustForCertificates:(NSArray*)certificates policies:(NSArray*)policies; 31 | + (Trust*)trustWithTrustRef:(SecTrustRef)tru; 32 | 33 | - (Trust*)initForCertificates:(NSArray*)certificates policies:(NSArray*)policies; 34 | - (Trust*)initWithTrustRef:(SecTrustRef)tru; 35 | 36 | /*! @method init 37 | @abstract Reject initialiser. 38 | @discussion You cannot initialise a Trust using "init" - use one of the other initialisation methods. 39 | @result This method always releases the receiver and returns nil. */ 40 | 41 | - (Trust*)init; 42 | 43 | - (void)makeTrustForKeychains:(NSArray*)chains; 44 | 45 | - (void)allowExpiredCertificates:(BOOL)allow; 46 | 47 | - (BOOL)canEvaluate; 48 | 49 | - (BOOL)isInvalid; 50 | - (BOOL)canProceed; 51 | - (BOOL)needsConfirmation; 52 | - (BOOL)userDenied; 53 | - (BOOL)userDidNotSpecify; 54 | - (BOOL)hasRecoverableFailure; 55 | - (BOOL)hasFatalFailure; 56 | - (BOOL)hasUnknownError; 57 | 58 | /*! @method lastError 59 | @abstract Returns the last error that occured for the receiver. 60 | @discussion The set of error codes encompasses those returned by Sec* functions - refer to the Security framework documentation for a list. At present there are no other error codes defined for Access instances. 61 | 62 | Please note that this error code is local to the receiver only, and not any sort of shared global value. 63 | @result The last error that occured, or zero if the last operation was successful. */ 64 | 65 | - (int)lastError; 66 | - (SecTrustRef)trustRef; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Keychain/MutableKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // MutableKey.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sat Mar 15 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | 17 | 18 | @interface MutableKey : Key { 19 | CSSM_KEY *MutableCSSMKey; 20 | BOOL freeWhenDone; 21 | } 22 | 23 | + (MutableKey*)generateKey:(CSSM_ALGORITHMS)algorithm size:(uint32)keySizeInBits validFrom:(NSCalendarDate*)validFrom validTo:(NSCalendarDate*)validTo usage:(uint32)keyUsage mutable:(BOOL)keyIsMutable extractable:(BOOL)keyIsExtractable sensitive:(BOOL)keyIsSensitive label:(NSString*)label; 24 | 25 | + (MutableKey*)keyWithKeyRef:(SecKeyRef)ke; 26 | + (MutableKey*)keyWithCSSMKey:(CSSM_KEY*)ke; 27 | + (MutableKey*)keyWithCSSMKey:(CSSM_KEY*)ke freeWhenDone:(BOOL)freeWhenDo; 28 | 29 | - (MutableKey*)initWithKeyRef:(SecKeyRef)ke; 30 | - (MutableKey*)initWithCSSMKey:(CSSM_KEY*)ke freeWhenDone:(BOOL)freeWhenDo; 31 | 32 | /*! @method init 33 | @abstract Reject initialiser. 34 | @discussion You cannot initialise a MutableKey using "init" - use one of the other initialisation methods. 35 | @result This method always releases the receiver and returns nil. */ 36 | 37 | - (MutableKey*)init; 38 | 39 | - (void)setFreeWhenDone:(BOOL)freeWhenDo; 40 | - (BOOL)freeWhenDone; 41 | 42 | - (void)setVersion:(CSSM_HEADERVERSION)version; 43 | - (void)setBlobType:(CSSM_KEYBLOB_TYPE)blobType; 44 | - (void)setFormat:(CSSM_KEYBLOB_FORMAT)format; 45 | - (void)setAlgorithm:(CSSM_ALGORITHMS)algorithm; 46 | - (void)setWrapAlgorithm:(CSSM_ALGORITHMS)wrapAlgorithm; 47 | - (void)setKeyClass:(CSSM_KEYCLASS)keyClass; 48 | - (void)setLogicalSize:(int)size; 49 | - (void)setAttributes:(CSSM_KEYATTR_FLAGS)attributes; 50 | - (void)setUsage:(CSSM_KEYUSE)usage; 51 | - (void)setStartDate:(NSCalendarDate*)date; 52 | - (void)setEndDate:(NSCalendarDate*)date; 53 | - (void)setWrapMode:(CSSM_ENCRYPT_MODE)wrapMode; 54 | 55 | - (void)setData:(NSData*)data; 56 | 57 | - (CSSM_KEY*)CSSMKey; 58 | 59 | @end 60 | 61 | NSArray* generateKeyPair(CSSM_ALGORITHMS algorithm, uint32 keySizeInBits, NSCalendarDate *validFrom, NSCalendarDate *validTo, uint32 publicKeyUsage, uint32 privateKeyUsage, NSString *publicKeyLabel, NSString *privateKeyLabel); 62 | -------------------------------------------------------------------------------- /Keychain/KeychainUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainUtils.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed May 14 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "KeychainUtils.h" 15 | 16 | #import "CSSMControl.h" 17 | #import "CSSMErrors.h" 18 | #import "Logging.h" 19 | 20 | 21 | char* generateRandomData(uint32 lengthInBytes, CSSM_ALGORITHMS algorithm, const char *seed, unsigned int seedLength) { 22 | CSSM_CC_HANDLE ccHandle; 23 | static CSSM_CRYPTO_DATA rawSeed; 24 | static CSSM_CRYPTO_DATA_PTR rawSeedPtr; 25 | static CSSM_DATA result; 26 | CSSM_RETURN err; 27 | char *finalResult = NULL; 28 | 29 | if (seed && (seedLength > 0)) { 30 | rawSeedPtr = &rawSeed; 31 | rawSeed.Callback = NULL; 32 | rawSeed.CallerCtx = NULL; 33 | rawSeed.Param.Length = seedLength; 34 | rawSeed.Param.Data = (uint8_t*)seed; 35 | } else { 36 | rawSeedPtr = NULL; 37 | } 38 | 39 | if ((err = CSSM_CSP_CreateRandomGenContext(keychainFrameworkCSPHandle(), algorithm, rawSeedPtr, lengthInBytes, &ccHandle)) == CSSM_OK) { 40 | result.Length = 0; 41 | result.Data = NULL; 42 | 43 | if ((err = CSSM_GenerateRandom(ccHandle, &result)) == CSSM_OK) { 44 | if (result.Length != lengthInBytes) { 45 | PDEBUG(@"CSSM_GenerateRandom(%d, %p) succeeded but returned a result of length %d, not %d.\n", ccHandle, &result, result.Length, lengthInBytes); 46 | } else { 47 | finalResult = (char*)(result.Data); 48 | } 49 | } else { 50 | PCONSOLE(@"Unable to generate random data because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 51 | PDEBUG(@"CSSM_GenerateRandom(%d, %p) returned error #%u (%@).\n", ccHandle, &result, err, CSSMErrorAsString(err)); 52 | } 53 | } else { 54 | PCONSOLE(@"Unable to create random data generation context because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 55 | PDEBUG(@"CSSM_CSP_CreateRandomGenContext(X, %d, %p, %d, %p [%d]) returned error #%u (%@).\n", algorithm, rawSeedPtr, lengthInBytes, &ccHandle, ccHandle, err, CSSMErrorAsString(err)); 56 | } 57 | 58 | return finalResult; 59 | } 60 | 61 | NSData* generateRandomNSData(uint32 lengthInBytes, CSSM_ALGORITHMS algorithm, NSData *seed) { 62 | char *temp = generateRandomData(lengthInBytes, algorithm, (seed ? [seed bytes] : NULL), (seed ? [seed length] : 0)); 63 | 64 | if (temp) { 65 | return [NSData dataWithBytesNoCopy:temp length:lengthInBytes]; 66 | } else { 67 | return nil; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Keychain/TrustedApplication.m: -------------------------------------------------------------------------------- 1 | // 2 | // TrustedApplication.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "TrustedApplication.h" 15 | 16 | 17 | @implementation TrustedApplication 18 | 19 | + (TrustedApplication*)trustedApplicationWithPath:(NSString*)path { 20 | return [[[[self class] alloc] initWithPath:path] autorelease]; 21 | } 22 | 23 | + (TrustedApplication*)trustedApplicationWithTrustedApplicationRef:(SecTrustedApplicationRef)trustedApp { 24 | return [[[[self class] alloc] initWithTrustedApplicationRef:trustedApp] autorelease]; 25 | } 26 | 27 | - (TrustedApplication*)initWithPath:(NSString*)path { 28 | error = SecTrustedApplicationCreateFromPath((path ? [path cString] : NULL), &trustedApplication); 29 | 30 | if (error == 0) { 31 | self = [super init]; 32 | 33 | return self; 34 | } else { 35 | [self release]; 36 | 37 | return nil; 38 | } 39 | } 40 | 41 | - (TrustedApplication*)initWithTrustedApplicationRef:(SecTrustedApplicationRef)trustedApp { 42 | TrustedApplication *existingObject; 43 | 44 | if (trustedApp) { 45 | existingObject = [[self class] instanceWithKey:(id)trustedApp from:@selector(trustedApplicationRef) simpleKey:NO]; 46 | 47 | if (existingObject) { 48 | [self release]; 49 | 50 | return [existingObject retain]; 51 | } else { 52 | if (self = [super init]) { 53 | CFRetain(trustedApp); 54 | trustedApplication = trustedApp; 55 | } 56 | 57 | return self; 58 | } 59 | } else { 60 | [self release]; 61 | 62 | return nil; 63 | } 64 | } 65 | 66 | - (TrustedApplication*)init { 67 | return [self initWithPath:nil]; 68 | } 69 | 70 | - (void)setData:(NSData*)data { 71 | error = SecTrustedApplicationSetData(trustedApplication, (CFDataRef)data); 72 | } 73 | 74 | - (NSData*)data { 75 | CFDataRef result; 76 | 77 | error = SecTrustedApplicationCopyData(trustedApplication, &result); 78 | 79 | if (error == 0) { 80 | return [(NSData*)result autorelease]; 81 | } else { 82 | return nil; 83 | } 84 | } 85 | 86 | - (int)lastError { 87 | return error; 88 | } 89 | 90 | - (SecTrustedApplicationRef)trustedApplicationRef { 91 | return trustedApplication; 92 | } 93 | 94 | - (void)dealloc { 95 | if (trustedApplication) { 96 | CFRelease(trustedApplication); 97 | } 98 | 99 | [super dealloc]; 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /Keychain/CSSMDefaults.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMDefaults.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed May 07 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "CSSMDefaults.h" 15 | 16 | #import "CSSMUtils.h" 17 | #import "Logging.h" 18 | 19 | 20 | /* The init vector really should be unique per cryptographic operation which uses it. It's presence is unfortunate and it is considered obsolete - it will be removed in a future version of the Keychain framework. */ 21 | 22 | uint8 keychainFrameworkInitVector[16]; /* = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; */ 23 | const CSSM_DATA keychainFrameworkInitVectorData = {16, keychainFrameworkInitVector}; 24 | 25 | const uint32 RAW_KEY_VERSION_1 = 1; 26 | const uint32 KEYHEADER_VERSION_1_SIZE = 76; 27 | 28 | 29 | CSSM_ENCRYPT_MODE defaultModeForAlgorithm(CSSM_ALGORITHMS algorithm) { 30 | switch(algorithm) { 31 | /* 8-byte block ciphers */ 32 | case CSSM_ALGID_DES: 33 | case CSSM_ALGID_3DES_3KEY_EDE: 34 | case CSSM_ALGID_RC5: 35 | case CSSM_ALGID_RC2: 36 | return CSSM_ALGMODE_CBCPadIV8; break; 37 | /* 16-byte block ciphers */ 38 | case CSSM_ALGID_AES: 39 | return CSSM_ALGMODE_CBCPadIV8; break; 40 | /* stream ciphers */ 41 | case CSSM_ALGID_ASC: 42 | case CSSM_ALGID_RC4: 43 | return CSSM_ALGMODE_NONE; break; 44 | /* Unknown */ 45 | default: 46 | PDEBUG(@"Asked for the default mode for \"%@\" (%d), but don't know that algorithm.\n", nameOfAlgorithm(algorithm), algorithm); 47 | return CSSM_ALGMODE_NONE; 48 | } 49 | } 50 | 51 | CSSM_PADDING defaultPaddingForAlgorithm(CSSM_ALGORITHMS algorithm) { 52 | switch(algorithm) { 53 | /* 8-byte block ciphers */ 54 | case CSSM_ALGID_DES: 55 | case CSSM_ALGID_3DES_3KEY_EDE: 56 | case CSSM_ALGID_RC5: 57 | case CSSM_ALGID_RC2: 58 | return CSSM_PADDING_PKCS5; break; 59 | /* 16-byte block ciphers */ 60 | case CSSM_ALGID_AES: 61 | return CSSM_PADDING_PKCS7; break; 62 | /* stream ciphers */ 63 | case CSSM_ALGID_ASC: 64 | case CSSM_ALGID_RC4: 65 | return CSSM_PADDING_NONE; break; 66 | /* RSA/DSA asymmetric */ 67 | case CSSM_ALGID_DSA: 68 | case CSSM_ALGID_RSA: 69 | return CSSM_PADDING_PKCS1; break; 70 | /* Unknown */ 71 | default: 72 | PDEBUG(@"Asked for the default padding mode for \"%@\" (%d), but don't know that algorithm.\n", nameOfAlgorithm(algorithm), algorithm); 73 | return CSSM_PADDING_NONE; 74 | } 75 | } 76 | 77 | CSSM_ALGORITHMS defaultDigestForAlgorithm(CSSM_ALGORITHMS algorithm) { 78 | switch (algorithm) { 79 | case CSSM_ALGID_RSA: 80 | return CSSM_ALGID_SHA1WithRSA; break; 81 | case CSSM_ALGID_DSA: 82 | return CSSM_ALGID_SHA1WithDSA; break; 83 | case CSSM_ALGID_FEE: 84 | return CSSM_ALGID_FEE_SHA1; break; 85 | default: 86 | PDEBUG(@"Asked for the default digest algorithm for \"%@\" (%d), but don't know that algorithm.\n", nameOfAlgorithm(algorithm), algorithm); 87 | return CSSM_ALGID_NONE; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Keychain/CSSMInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMInfo.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Thu Jul 08 2004. 6 | // 7 | // Copyright (c) 2004, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | 15 | #import 16 | #import 17 | 18 | 19 | extern NSString *USER_AUTHENTICATED; // True if the user has authenticated on the token 20 | 21 | extern NSString *TOKEN_WRITE_PROTECTED; // Service provider is write protected 22 | extern NSString *TOKEN_LOGIN_REQUIRED; // User must login to access private objects. 23 | extern NSString *TOKEN_USER_PIN_INITIALIZED; // User's PIN has been initialized. 24 | extern NSString *TOKEN_PROT_AUTHENTICATION; // Service provider has protected authentication path for entering a user PIN. No password should be supplied to the CSSM_CSP_Login API. 25 | extern NSString *TOKEN_USER_PIN_EXPIRED; // The user PIN must be changed before the service provider can be used. 26 | extern NSString *TOKEN_SESSION_KEY_PASSWORD; // Session keys held by the CSP require individual passwords, possibly in addition to a login password. 27 | extern NSString *TOKEN_PRIVATE_KEY_PASSWORD; // Private keys held by the CSP require individual passwords, possibly in addition to a login password 28 | extern NSString *TOKEN_STORES_PRIVATE_KEYS; // CSP can store private keys. 29 | extern NSString *TOKEN_STORES_PUBLIC_KEYS; // CSP can store public keys. 30 | extern NSString *TOKEN_STORES_SESSION_KEYS; // CSP can store session/secret keys 31 | extern NSString *TOKEN_STORES_CERTIFICATES; // Service provider can store certs using DL APIs. 32 | extern NSString *TOKEN_STORES_GENERIC; // Service provider can store generic objects using DL APIs. 33 | 34 | extern NSString *MAX_SESSION_COUNT; // Maximum number of CSP handles referencing the token that may exist simultaneously. 35 | extern NSString *OPEN_SESSION_COUNT; // Number of existing CSP handles referencing the token. 36 | extern NSString *MAX_RW_SESSION_COUNT; // Maximum number of CSP handles that can reference the token simultaneously in read-write mode. 37 | extern NSString *OPEN_RW_SESSION_COUNT; // Number of existing CSP handles referencing the token in read-write mode. 38 | extern NSString *TOTAL_PUBLIC_MEMORY; // Amount of public storage space in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 39 | extern NSString *FREE_PUBLIC_MEMORY; // Amount of public storage space available for use in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 40 | extern NSString *TOTAL_PRIVATE_MEMORY; // Amount of private storage space in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 41 | extern NSString *FREE_PRIVATE_MEMORY; // Amount of private storage space available for use in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 42 | 43 | /*! @function cssmOperatingStatistics 44 | @abstract Returns a variety of operational statistics about a particular CSP module. 45 | @discussion Most of the information returned by this function is only interesting for curiosities sake. Things such as memory use, capabilities of the CSP in a general sense, etc. It's primary purpose is with the use of CSP-capable "tokens" - e.g. smartcards and similar devices. 46 | 47 | Note that statistics are not presently available from any other modules, e.g. CLs or TPs. This is a limitation of the CDSA. 48 | @param handle A handle for the CSP module to query. 49 | @result Returns a dictionary containing zero or more key-value pairs. You can use the constants declared in this header to query specific items. If an error occurs, nil is returned. */ 50 | 51 | NSDictionary* cspOperatingStatistics(CSSM_CSP_HANDLE handle); 52 | -------------------------------------------------------------------------------- /Keychain/FileUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // FileUtilities.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sun Jan 25 2004. 6 | // Copyright (c) 2004 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "FileUtilities.h" 10 | 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | #import "UtilitySupport.h" 18 | #import "CSSMErrors.h" 19 | #import "CSSMControl.h" 20 | #import "Logging.h" 21 | 22 | 23 | NSData* digestOfPath(NSString* path, CSSM_ALGORITHMS algorithm) { 24 | CSSM_RETURN err; 25 | CSSM_CC_HANDLE ccHandle; 26 | CSSM_DATA result, original; 27 | NSData *finalResult = nil; 28 | int theFile; 29 | const unsigned long BUFFER_SIZE = 1048576; 30 | unsigned long bufferSize; 31 | struct stat fileStats; 32 | 33 | if ((err = CSSM_CSP_CreateDigestContext(keychainFrameworkCSPHandle(), algorithm, &ccHandle)) == CSSM_OK) { 34 | if ((err = CSSM_DigestDataInit(ccHandle)) == CSSM_OK) { 35 | theFile = open([path UTF8String], O_RDONLY, 0); 36 | 37 | if (theFile >= 0) { 38 | if (0 == fstat(theFile, &fileStats)) { 39 | if (fileStats.st_size < BUFFER_SIZE) { 40 | bufferSize = fileStats.st_size; 41 | } else if ((fileStats.st_size / 2) < BUFFER_SIZE) { 42 | bufferSize = fileStats.st_size / 2; 43 | } else if ((fileStats.st_size / 3) < BUFFER_SIZE) { 44 | bufferSize = fileStats.st_size / 3; 45 | } else { 46 | bufferSize = BUFFER_SIZE; // 1 mibibyte at a time 47 | } 48 | 49 | original.Data = malloc(bufferSize); 50 | 51 | while ((original.Length = read(theFile, original.Data, bufferSize)) > 0) { 52 | if ((err = CSSM_DigestDataUpdate(ccHandle, &original, 1)) != CSSM_OK) { 53 | PCONSOLE(@"Unable to generate digest because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 54 | PDEBUG(@"CSSM_DigestDataUpdate(%d, %p, 1) returned error #%u (%@).\n", ccHandle, &original, err, CSSMErrorAsString(err)); 55 | 56 | free(original.Data); 57 | 58 | return nil; 59 | } 60 | } 61 | 62 | if (original.Length >= 0) { 63 | result.Length = 0; 64 | result.Data = NULL; 65 | 66 | if ((err = CSSM_DigestDataFinal(ccHandle, &result)) == CSSM_OK) { 67 | finalResult = NSDataFromDataNoCopy(&result, YES); 68 | } else { 69 | PCONSOLE(@"Unable to retrieve final digest because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 70 | PDEBUG(@"CSSM_DigestDataFinal(%d, %p) returned error #%u (%@).\n", ccHandle, &result, err, CSSMErrorAsString(err)); 71 | } 72 | 73 | if ((err = CSSM_DeleteContext(ccHandle)) != CSSM_OK) { 74 | PCONSOLE(@"Warning: Failed to destroy digest context because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 75 | PDEBUG(@"CSSM_DeleteContext(%d) returned error #%u (%@).\n", ccHandle, err, CSSMErrorAsString(err)); 76 | } 77 | } else { 78 | PCONSOLE(@"Unable to read from file because of error #%d (%s).\n", errno, strerror(errno)); 79 | PDEBUG(@"read(%d, %p, %d) returned error #%d (%s).\n", theFile, original.Data, bufferSize, errno, strerror(errno)); 80 | } 81 | 82 | free(original.Data); 83 | } else { 84 | PCONSOLE(@"Unable to stat file to determine length because of error #%d (%s).\n", errno, strerror(errno)); 85 | PDEBUG(@"fstat(%d, %p) returned error #%d (%s).\n", theFile, &fileStats, errno, strerror(errno)); 86 | } 87 | } else { 88 | PCONSOLE(@"Unable to calculate digest of file \"%@\" because it does not exist or is not readable (error #%d (%s)).\n", path, errno, strerror(errno)); 89 | PDEBUG(@"open(\"%@\", O_RDONLY, 0) returned error #%d (%s).\n", path, errno, strerror(errno)); 90 | } 91 | } else { 92 | PCONSOLE(@"Unable to initialise digest because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 93 | PDEBUG(@"CSSM_DigestDataInit(%d) returned error #%u (%@).\n", ccHandle, err, CSSMErrorAsString(err)); 94 | } 95 | } else { 96 | PCONSOLE(@"Unable to create digest context because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 97 | PDEBUG(@"CSSM_CSP_CreateDigestContext(X, %d, %p [%d]) returned error #%u (%@).\n", algorithm, &ccHandle, ccHandle, err, CSSMErrorAsString(err)); 98 | } 99 | 100 | return finalResult; 101 | } 102 | -------------------------------------------------------------------------------- /Keychain/Identity.m: -------------------------------------------------------------------------------- 1 | // 2 | // Identity.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "Identity.h" 15 | 16 | #import "Logging.h" 17 | 18 | 19 | @implementation Identity 20 | 21 | + (Identity*)identityWithIdentityRef:(SecIdentityRef)ident { 22 | return [[[[self class] alloc] initWithIdentityRef:ident] autorelease]; 23 | } 24 | 25 | + (Identity*)identityWithCertificate:(Certificate*)certificate privateKey:(Key*)privateKey inKeychain:(Keychain*)keychain label:(NSString*)label { 26 | if (certificate && privateKey && keychain) { 27 | [keychain addCertificate:certificate privateKey:privateKey withName:label]; 28 | 29 | if ([keychain lastError] == CSSM_OK) { 30 | NSArray *idents = [[keychain identitiesForUse:[privateKey usage]] retain]; 31 | 32 | if (idents) { 33 | NSEnumerator *enumerator = [idents objectEnumerator]; 34 | Identity *current; 35 | 36 | while (current = [enumerator nextObject]) { 37 | if ([[current certificate] isEqualToCertificate:certificate]) { 38 | // We need to retain the identity, because it's currently only retained by the idents array and we don't want it disappearing when that array does. But we need to return it autoreleased in order to maintain expected class constructor behaviour. 39 | 40 | [current retain]; 41 | [idents release]; 42 | 43 | return [current autorelease]; 44 | } 45 | } 46 | 47 | PDEBUG(@"I was able to create and add the identity, but then... umm... well, um.. lost it. Sorry. Although there was a list of identities retrieved from the keychain, the new one wasn't in there.\n"); 48 | } else { 49 | PDEBUG(@"I was able to create and add the identity, but then... umm... well, um.. lost it. Sorry. This was due to an error searching for identities in the keychain.\n"); 50 | } 51 | } else { 52 | PDEBUG(@"Unable to add the certificate and private key to the given keychain.\n"); 53 | } 54 | } else { 55 | PDEBUG(@"Invalid parameters (identityWithCertificate:%p privateKey:%p inKeychain:%p label:%p).\n", certificate, privateKey, keychain, label); 56 | } 57 | 58 | return nil; 59 | } 60 | 61 | - (Identity*)initWithIdentityRef:(SecIdentityRef)ident { 62 | Identity *existingObject; 63 | 64 | if (ident) { 65 | existingObject = [[self class] instanceWithKey:(id)ident from:@selector(identityRef) simpleKey:NO]; 66 | 67 | if (existingObject) { 68 | [self release]; 69 | 70 | self = [existingObject retain]; 71 | } else { 72 | if (self = [super init]) { 73 | CFRetain(ident); 74 | identity = ident; 75 | } 76 | } 77 | } else { 78 | [self release]; 79 | self = nil; 80 | } 81 | 82 | return self; 83 | } 84 | 85 | - (Identity*)init { 86 | [self release]; 87 | return nil; 88 | } 89 | 90 | - (Certificate*)certificate { 91 | SecCertificateRef result = NULL; 92 | Certificate *res; 93 | 94 | error = SecIdentityCopyCertificate(identity, &result); 95 | 96 | if ((error == 0) && result) { 97 | res = [Certificate certificateWithCertificateRef:result]; 98 | 99 | CFRelease(result); 100 | 101 | return res; 102 | } else { 103 | return nil; 104 | } 105 | } 106 | 107 | - (Key*)publicKey { 108 | return [[self certificate] publicKey]; 109 | } 110 | 111 | - (Key*)privateKey { 112 | SecKeyRef result = NULL; 113 | Key *res; 114 | 115 | error = SecIdentityCopyPrivateKey(identity, &result); 116 | 117 | if ((error == 0) && result) { 118 | res = [Key keyWithKeyRef:result]; 119 | 120 | CFRelease(result); 121 | 122 | return res; 123 | } else { 124 | return nil; 125 | } 126 | } 127 | 128 | - (NSString*)description { 129 | return [NSString stringWithFormat:@"Certificate: %@\nPrivate key: %@", [[self certificate] description], [[self privateKey] description]]; 130 | } 131 | 132 | - (int)lastError { 133 | return error; 134 | } 135 | 136 | - (SecIdentityRef)identityRef { 137 | return identity; 138 | } 139 | 140 | - (void)dealloc { 141 | if (identity) { 142 | CFRelease(identity); 143 | } 144 | 145 | [super dealloc]; 146 | } 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /Keychain/NSCachedObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSCachedObject.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sun Feb 16 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "NSCachedObject.h" 15 | 16 | #import 17 | 18 | 19 | @implementation NSCachedObject 20 | 21 | 22 | static NSMutableDictionary *objectDictionary; 23 | 24 | 25 | // As you can see, the methods below are designed to be thread safe, if keychainCachedObjectLock exists. In this particular implementation, keychainCachedObjectLock is defined in MultiThreading.h. If you wish to maintain thread safe code while using this class in your own project, simply copy the keychainCachedObjectLock definition from MultiThreading.h into this file. Remember if you do this that you will have to initialize this lock prior to your application becoming multi-threaded (e.g. prior to executing any run loops, or when you receive a NSWillBecomeMultiThreadedNotification notification, etc). 26 | 27 | + (id)instanceWithKey:(id)key from:(SEL)selector simpleKey:(BOOL)simpleKey { 28 | NSEnumerator *enumerator; 29 | id current, finalResult = nil; 30 | NSMutableArray *objectArray; 31 | 32 | if (objectDictionary) { 33 | [keychainCachedObjectLock lock]; 34 | 35 | objectArray = [objectDictionary objectForKey:[self class]]; 36 | 37 | if (objectArray) { 38 | enumerator = [objectArray objectEnumerator]; 39 | 40 | // Note that the following does duplicate a lot of code, having two near-identical loops side by side. But the point is to make sure only one branch is done on simpleKey, rather than once for each entry in the object cache, of which there may be many. 41 | 42 | if (simpleKey) { 43 | while (current = [enumerator nextObject]) { 44 | if ([current respondsToSelector:selector]) { 45 | if ([current performSelector:selector] == key) { 46 | finalResult = current; 47 | break; 48 | } 49 | } 50 | } 51 | } else { 52 | while (current = [enumerator nextObject]) { 53 | if ([current respondsToSelector:selector]) { 54 | if ([key isEqual:[current performSelector:selector]]) { 55 | finalResult = current; 56 | break; 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | [keychainCachedObjectLock unlock]; 64 | } 65 | 66 | return finalResult; 67 | } 68 | 69 | + (id)instanceForSelector:(SEL)selector with:(id)key { 70 | NSEnumerator *enumerator; 71 | id current, finalResult = nil; 72 | NSMutableArray *objectArray; 73 | 74 | if (objectDictionary) { 75 | [keychainCachedObjectLock lock]; 76 | 77 | objectArray = [objectDictionary objectForKey:[self class]]; 78 | 79 | if (objectArray) { 80 | enumerator = [objectArray objectEnumerator]; 81 | 82 | while (current = [enumerator nextObject]) { 83 | if ([current respondsToSelector:selector]) { 84 | if ([current performSelector:selector withObject:key]) { 85 | finalResult = current; 86 | break; 87 | } 88 | } 89 | } 90 | } 91 | 92 | [keychainCachedObjectLock unlock]; 93 | } 94 | 95 | return finalResult; 96 | } 97 | 98 | - (id)init { 99 | NSMutableArray *objectArray; 100 | 101 | if (self = [super init]) { 102 | [keychainCachedObjectLock lock]; 103 | 104 | if (!objectDictionary) { 105 | objectDictionary = [[NSMutableDictionary dictionaryWithCapacity:5] retain]; 106 | } 107 | 108 | objectArray = [objectDictionary objectForKey:[self class]]; 109 | 110 | if (!objectArray) { 111 | objectArray = [NSMutableArray arrayWithCapacity:10]; 112 | [objectDictionary setObject:objectArray forKey:[self class]]; 113 | } 114 | 115 | [objectArray addObject:self]; 116 | 117 | [keychainCachedObjectLock unlock]; 118 | } 119 | 120 | return self; 121 | } 122 | 123 | - (void)dealloc { 124 | NSMutableArray *objectArray = [objectDictionary objectForKey:[self class]]; 125 | 126 | [keychainCachedObjectLock lock]; 127 | [objectArray removeObject:self]; 128 | [keychainCachedObjectLock unlock]; 129 | 130 | [super dealloc]; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /Keychain/CertificateGeneration.h: -------------------------------------------------------------------------------- 1 | // 2 | // CertificateGeneration.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Tue May 27 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | 20 | 21 | /*! @function createCertificateTemplate 22 | @abstract Creates a certificate template from a series of generic properties. 23 | @discussion This function takes the parameters given, some optional, and creates some data represeting a certificate, in a kind of template form. This data can then be signed to create a full certificate. 24 | @param subject The name of the subject of the certificate - i.e. who it represents. This parameter is required. 25 | @param issuer The name of the person or authority which will issue the certificate. This parameter is required. 26 | @param validity The times when the certificate will be valid. This parameter is optional. 27 | @param publicKey The public key of the subject of the certificate. This is usually always the public key of the subject. This parameter is required. 28 | @param signingAlgorithm The algorithm you intend to use to sign the certificate. The signing algorithm includes a hash, so if you're using RSA, this algorithm should be something like SHA1 with RSA. This parameter is required. 29 | @param serialNumber The serial number to be given to the certificate. This parameter is optional. 30 | @param extensions A list of extensions to be included in the certificate. This parameter is optional. 31 | @result Provided all the parameters are valid and the required ones present, a NSData instance containing the certificate template is returned. Otherwise, nil is returned. */ 32 | 33 | NSData* createCertificateTemplate(NameList *subject, NameList *issuer, Validity *validity, Key *publicKey, AlgorithmIdentifier *signingAlgorithm, NSData *serialNumber, ExtensionList *extensions); 34 | 35 | /*! @function signCertificate 36 | @abstract Signs a certificate template with a given private key. 37 | @discussion This function takes the certificate template supplied and signs it with the private key supplied, returning the signed certificate in raw data form. 38 | @param certificate The certificate template to be signed. A certificate template can be generated using createCertificateTemplate. 39 | @param privateKey The private key with which to sign the certificate. This should be the issuer's private key. 40 | @param signingAlgorithm The algorithm to sign the certificate with. The signing procedure requires a hash to be performed, so the algorithm should be something like CSSM_ALGID_SHA1WithRSA, not CSSM_ALGID_RSA. This should match the algorithm passed to createCertificateTemplate - indeed, you can retrieve the appropriate CSSM_ALGORITHMS code using [AlgorithmIdentifier algorithm]. 41 | @result If the certificate template and private key are valid, the signed certificate's data is returned. Otherwise, nil is returned. */ 42 | 43 | NSData* signCertificate(NSData *certificate, Key *privateKey, CSSM_ALGORITHMS signingAlgorithm); 44 | 45 | /*! @function createCertificate 46 | @abstract Creates and signs a new certificate. 47 | @discussion This function simply provides a nice little wrapper around the createCertificateTemplate and signCertificate functions. 48 | @param subject The name of the subject of the certificate - i.e. who it represents. This parameter is required. 49 | @param issuer The name of the person or authority which will issue the certificate. This parameter is required and may not be nil. To create a self-signed certificate, simply pass the subject name in for this parameter. 50 | @param validity The times when the certificate will be valid. This parameter is optional. 51 | @param publicKey The public key of the subject of the certificate. This is usually always the public key of the subject. This parameter is required. 52 | @param privateKey The private key with which to sign the certificate. This should be the issuer's private key. 53 | @param signingAlgorithm The algorithm you intend to use to sign the certificate. The signing algorithm includes a hash, so if you're using RSA, this algorithm should be something like SHA1 with RSA. This parameter is required. 54 | @param serialNumber The serial number to be given to the certificate. This parameter is optional - if it is zero, it is ignored. 55 | @param extensions A list of extensions to be included in the certificate. This parameter is optional. 56 | @result Returns a new Certificate instance, or nil if an error occurs. */ 57 | 58 | Certificate *createCertificate(NameList *subject, NameList *issuer, Validity *validity, Key *publicKey, Key *privateKey, AlgorithmIdentifier *signingAlgorithm, NSData *serialNumber, ExtensionList *extensions); -------------------------------------------------------------------------------- /Keychain/KeychainSearch.h: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainSearch.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | /*! @function FindCertificatesMatchingPublicKeyHash 20 | @abstract Locates and returns all certificates in the current user's keychain(s) matching the public key hash given. 21 | @discussion This method locates all the certificates matching the given public key hash in the current user's default keychain(s). It returns nil if not found, the certificate otherwise. 22 | 23 | Note that this function is currently extremely inoptimal. If performance is poor, please log a bug report to encourage it to be rewritten, or better yet rewrite it yourself. :) 24 | @param hash The hash of the public key for which to find certificates. 25 | @result An array of certificates, which may be empty if no matches are found. Nil is returned on error. */ 26 | 27 | NSArray* FindCertificatesMatchingPublicKeyHash(NSData *hash); 28 | 29 | 30 | @interface SearchAttribute : NSObject { 31 | SecKeychainAttribute attribute; 32 | BOOL freeWhenDone; 33 | } 34 | 35 | + (SearchAttribute*)attributeWithTag:(SecKeychainAttrType)tag length:(UInt32)length data:(void*)data freeWhenDone:(BOOL)fre; 36 | + (SearchAttribute*)attributeWithTag:(SecKeychainAttrType)tag length:(UInt32)length data:(const void *)data; 37 | 38 | - (SearchAttribute*)initWithTag:(SecKeychainAttrType)tag length:(UInt32)length data:(void*)data freeWhenDone:(BOOL)fre; 39 | - (SearchAttribute*)initWithTag:(SecKeychainAttrType)tag length:(UInt32)length data:(const void *)data; 40 | 41 | /*! @method init 42 | @abstract Reject initialiser. 43 | @discussion You cannot initialise a SearchAttribute using "init" - use one of the other initialisation methods. 44 | @result This method always releases the receiver and returns nil. */ 45 | 46 | - (SearchAttribute*)init; 47 | 48 | - (SecKeychainAttributePtr)attributePtr; 49 | 50 | @end 51 | 52 | 53 | 54 | @interface KeychainSearch : NSObject { 55 | NSArray *keychainList; 56 | NSMutableArray *attributes; 57 | int error; 58 | } 59 | 60 | + (KeychainSearch*)keychainSearchWithKeychains:(NSArray*)keychains; 61 | 62 | - (KeychainSearch*)initWithKeychains:(NSArray*)keychains; // parameter may now be NULL, in which case the behaviour is the same as for the init method 63 | 64 | /*! @method init 65 | @abstract Initialises the receiver to search the current user's default list of keychains. 66 | @discussion The user's default keychain list usually includes - at the very least - their own user keychain as well as the system keychain. It can, however, be configured by the user to be whatever they like. 67 | @result Returns the receiver is successful, otherwise releases the receiver and returns nil. */ 68 | 69 | - (KeychainSearch*)init; 70 | 71 | - (void)setCreationDate:(NSDate*)date; 72 | - (void)setModificationDate:(NSDate*)date; 73 | - (void)setDescription:(NSString*)desc; 74 | - (void)setComment:(NSString*)comment; 75 | - (void)setCreator:(NSString*)creator; 76 | - (void)setType:(NSString*)type; 77 | - (void)setLabel:(NSString*)label; 78 | - (void)setIsVisible:(BOOL)visible; 79 | - (void)setPasswordIsValid:(BOOL)valid; 80 | - (void)setHasCustomIcon:(BOOL)customIcon; 81 | - (void)setAccount:(NSString*)account; 82 | - (void)setService:(NSString*)service; 83 | - (void)setAttribute:(NSString*)attr; 84 | - (void)setDomain:(NSString*)domain; 85 | - (void)setServer:(NSString*)server; 86 | - (void)setAuthenticationType:(SecAuthenticationType)type; 87 | - (void)setPort:(UInt16)port; 88 | - (void)setPath:(NSString*)path; 89 | - (void)setAppleShareVolume:(NSString*)volume; 90 | - (void)setAppleShareAddress:(NSString*)address; 91 | - (void)setAppleShareSignature:(SecAFPServerSignature*)sig; 92 | - (void)setProtocol:(SecProtocolType)protocol; 93 | - (void)setCertificateType:(CSSM_CERT_TYPE)type; 94 | - (void)setCertificateEncoding:(CSSM_CERT_ENCODING)encoding; 95 | - (void)setCRLType:(CSSM_CRL_TYPE)type; 96 | - (void)setCRLEncoding:(CSSM_CRL_ENCODING)encoding; 97 | - (void)setIsAlias:(BOOL)alias; 98 | 99 | - (NSArray*)searchResultsForClass:(SecItemClass)class; 100 | 101 | - (NSArray*)anySearchResults; 102 | - (NSArray*)genericSearchResults; 103 | - (NSArray*)internetSearchResults; 104 | - (NSArray*)appleShareSearchResults; 105 | - (NSArray*)certificateSearchResults; 106 | 107 | /*! @method lastError 108 | @abstract Returns the last error that occured for the receiver. 109 | @discussion The set of error codes encompasses those returned by Sec* functions - refer to the Security framework documentation for a list. At present there are no other error codes defined for Access instances. 110 | 111 | Please note that this error code is local to the receiver only, and not any sort of shared global value. 112 | @result The last error that occured, or zero if the last operation was successful. */ 113 | 114 | - (int)lastError; 115 | - (NSArray*)keychains; 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /Keychain/SKeyPlus.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKeyPlus.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on 26/01/05. 6 | // Copyright 2005 Wade Tregaskis. All rights reserved. 7 | // 8 | 9 | #import "SKeyPlus.h" 10 | 11 | #import "CSSMDefaults.h" 12 | #import "CSSMControl.h" 13 | #import "CSSMErrors.h" 14 | #import "UtilitySupport.h" 15 | #import "Logging.h" 16 | 17 | 18 | @implementation SKeyPlusGenerator 19 | 20 | + (SKeyPlusGenerator*)generatorWithPassword:(NSString*)password uses:(unsigned int)uses { 21 | return [[[[self class] alloc] initWithPassword:password uses:uses] autorelease]; 22 | } 23 | 24 | - (int)generateCurrent { 25 | if (0 == usesRemaining) { 26 | return 0; 27 | } else { 28 | CSSM_RETURN err; 29 | CSSM_CC_HANDLE ccHandle; 30 | CSSM_DATA result, original, *input = &original, *output = &result, *temp; 31 | NSData *finalResult = nil; 32 | unsigned int iterationsRemaining = usesRemaining; 33 | 34 | if ((err = CSSM_CSP_CreateDigestContext(keychainFrameworkCSPHandle(), CSSM_ALGID_SHA1, &ccHandle)) == CSSM_OK) { 35 | err = copyDataToData(&base, &original); 36 | 37 | if (0 == err) { 38 | 39 | err = CSSM_OK; 40 | 41 | while ((CSSM_OK == err) && (0 < iterationsRemaining)) { 42 | clearCSSMData(output); 43 | 44 | err = CSSM_DigestData(ccHandle, &original, 1, &result); 45 | 46 | if (err == CSSM_OK) { 47 | temp = input; 48 | input = output; 49 | output = temp; 50 | 51 | clearCSSMData(output); 52 | 53 | finalResult = NSDataFromDataNoCopy(&result, YES); 54 | } else { 55 | PCONSOLE(@"Unable to generate digest because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 56 | PDEBUG(@"CSSM_DigestData(%d, %p, 1, %p) returned error #%u (%@).\n", ccHandle, &original, &result, err, CSSMErrorAsString(err)); 57 | } 58 | } 59 | } else { 60 | PDEBUG(@"Unable to copy data to data, error #%d (%s).\n", err, strerror(err)); 61 | } 62 | 63 | err = CSSM_DeleteContext(ccHandle); 64 | 65 | if (err != CSSM_OK) { 66 | PCONSOLE(@"Warning: Failed to destroy digest context because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 67 | PDEBUG(@"CSSM_DeleteContext(%d) returned error #%u (%@).\n", ccHandle, err, CSSMErrorAsString(err)); 68 | } 69 | } else { 70 | PCONSOLE(@"Unable to create digest context because of error #%u - %@.\n", err, CSSMErrorAsString(err)); 71 | PDEBUG(@"CSSM_CSP_CreateDigestContext(X, CSSM_ALGID_SHA1, %p [%d]) returned error #%u (%@).\n", &ccHandle, ccHandle, err, CSSMErrorAsString(err)); 72 | } 73 | 74 | //return finalResult; 75 | return 0; 76 | } 77 | } 78 | 79 | - (SKeyPlusGenerator*)initWithPassword:(NSString*)password uses:(unsigned int)uses { 80 | if (password && (0 < uses)) { 81 | if (self = [super init]) { 82 | int err; 83 | 84 | err = copyNSStringToData(password, &base); 85 | 86 | if (0 != err) { 87 | PDEBUG(@"Unable to copy 'password' to 'base', error #%d (%d).\n", err, strerror(err)); 88 | [self release]; 89 | self = nil; 90 | } else { 91 | usesRemaining = uses; 92 | 93 | err = [self generateCurrent]; 94 | 95 | if (0 != err) { 96 | [self release]; 97 | self = nil; 98 | } 99 | } 100 | } 101 | } else { 102 | PDEBUG(@"Invalid parameters (password = %p, uses = %u).\n", password, uses); 103 | 104 | [self release]; 105 | self = nil; 106 | } 107 | 108 | return self; 109 | } 110 | 111 | - (unsigned int)usesRemaining { 112 | return usesRemaining; 113 | } 114 | 115 | - (NSData*)currentPassword { 116 | if (0 == usesRemaining) { 117 | return nil; 118 | } else { 119 | return NSDataFromData(¤t); 120 | } 121 | } 122 | 123 | - (NSData*)nextPassword { 124 | if (0 == usesRemaining) { 125 | return nil; 126 | } else { 127 | --usesRemaining; 128 | 129 | if (0 == usesRemaining) { 130 | clearCSSMData(¤t); 131 | 132 | return nil; 133 | } else { 134 | int err = [self generateCurrent]; 135 | 136 | if (0 != err) { 137 | PDEBUG(@"Unable to generate current password, error #%d (%s).\n", err, strerror(err)); 138 | return nil; 139 | } else { 140 | return NSDataFromData(¤t); 141 | } 142 | } 143 | } 144 | } 145 | 146 | @end 147 | 148 | 149 | @implementation SKeyPlusVerifier 150 | 151 | + (SKeyPlusVerifier*)verifierWithCurrentPassword:(NSData*)currentPassword usesRemaining:(unsigned int)currentUsesRemaining { 152 | return [[[[self class] alloc] initWithCurrentPassword:currentPassword usesRemaining:currentUsesRemaining] autorelease]; 153 | } 154 | 155 | - (SKeyPlusVerifier*)initWithCurrentPassword:(NSData*)currentPassword usesRemaining:(unsigned int)currentUsesRemaining { 156 | if (currentPassword && (0 < currentUsesRemaining)) { 157 | if (self = [super init]) { 158 | copyNSDataToData(currentPassword, ¤t); 159 | usesRemaining = currentUsesRemaining; 160 | 161 | allowSkips = NO; 162 | } 163 | } else { 164 | PDEBUG(@"Invalid parameters (currentPassword:%p currentUsesRemaining:%u).\n", currentPassword, currentUsesRemaining); 165 | 166 | [self release]; 167 | self = nil; 168 | } 169 | 170 | return self; 171 | } 172 | 173 | - (void)setAllowsSkips:(BOOL)shouldAllowSkips { 174 | allowSkips = shouldAllowSkips; 175 | } 176 | 177 | - (BOOL)allowsSkips { 178 | return allowSkips; 179 | } 180 | 181 | - (BOOL)verifyAgainst:(NSData*)password usesRemaining:(unsigned int)uses { 182 | /* TODO */ 183 | 184 | return NO; 185 | } 186 | 187 | - (BOOL)verifyAndUpdateAgainst:(NSData*)password usesRemaining:(unsigned int)uses { 188 | /* TODO */ 189 | 190 | return NO; 191 | } 192 | 193 | - (unsigned int)usesRemaining { 194 | return usesRemaining; 195 | } 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /Keychain/UtilitySupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // UtilitySupport.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | 17 | #import 18 | 19 | 20 | /*! @function allocCSSMData 21 | @abstract Allocates a new CSSM_DATA structure. 22 | @discussion This convenience function simply allocates and initialises (to an empty state) a CSSM_DATA structure. You could probably achieve the same effect with a simple call to calloc, but this way is more future compatible by virtue of it's abstraction. Consequently it should play a key role in maximizing shareholder value for the succeeding quarter looking forward. 23 | 24 | The returned CSSM_DATA is guaranteed to be in the same state as would be returned by a call to clearCSSMData. 25 | @result Returns a new empty CSSM_DATA if successful, NULL otherwise (which most likely indicates a memory allocation error). */ 26 | 27 | CSSM_DATA* allocCSSMData(void); 28 | 29 | /*! @function clearCSSMData 30 | @abstract Clears a CSSM_DATA structure back to it's default, empty state. 31 | @discussion This function releases the memory allocated to the data within the CSSM_DATA, and sets all other appropriate fields to 0 or similar. It does not free the memory used for the CSSM_DATA structure itself. 32 | 33 | The CSSM_DATA after calling is guaranteed to be in the same state as it would have been when first created using allocCSSMData. 34 | @param data The CSSM_DATA to return to the default, empty state. Should not be NULL. */ 35 | 36 | void clearCSSMData(CSSM_DATA *data); 37 | 38 | /*! @function freeCSSMData 39 | @abstract Frees all memory associated with a CSSM_DATA structure, including that of the structure itself. 40 | @discussion This function is similar to the clearCSSMData function, except it goes the extra step of freeing the CSSM_DATA structure itself, in addition to it's contents. 41 | 42 | The passed parameter will always be invalid after a call to this function. Note that you should always consider it invalid from the *start* of the call, if your application is multithreaded; it will most certainly pass through at least one invalid state during the function, which could create all kinds of havoc if another thread tries to use it. 43 | @param data The CSSM_DATA to free. It does not have to be already cleared using clearCSSMData. It is always invalid from the moment this function is called. Should not be NULL. */ 44 | 45 | void freeCSSMData(CSSM_DATA *data); 46 | 47 | /*! @function copyDataToData 48 | @abstract Copies a CSSM_DATA structure to another CSSM_DATA structure. 49 | @discussion The contents of 'source' are copied to 'destination'. The 'Data' field of destination may be free'd and re-malloc'd if necessary (or, it may be reused). In any case, don't rely on particular behaviour; it is undefined and indeed may vary both between versions and between parameter sets. 50 | @param source The source CSSM_DATA to be copied. Should not be NULL. If it is NULL, destination will be unmodified. 51 | @param destination The destination CSSM_DATA in which to copy the contents of 'source'. Should not be NULL. 52 | @result Returns 0 if successful, an error code (from ) otherwise. */ 53 | 54 | int copyDataToData(const CSSM_DATA *source, CSSM_DATA *destination); 55 | 56 | int copyNSStringToData(NSString *source, CSSM_DATA *destination); 57 | 58 | CSSM_DATA* dataFromNSString(NSString *string); 59 | 60 | void copyNSDataToData(NSData *source, CSSM_DATA *destination); 61 | 62 | // Be very careful using the following function - lots of stuff goes on inside the Keychain & Security frameworks, and the CDSA itself, even for simple requests. If you get malloc errors or BAD_ACCESS faults, you might want to check over any code which uses this method 63 | 64 | // P.S. Yes I know the function name contradicts itself. I'm lazy and it's consistent. 65 | 66 | void copyNSDataToDataNoCopy(NSData *source, CSSM_DATA *destination); 67 | 68 | CSSM_DATA* dataFromNSData(NSData *data); 69 | 70 | NSString* NSStringFromData(const CSSM_DATA *data); 71 | 72 | NSString* NSStringFromNSData(NSData *data); 73 | 74 | NSData* NSDataFromNSString(NSString *string); 75 | 76 | NSData* NSDataFromData(const CSSM_DATA *data); 77 | 78 | // Be very careful using the following function - lots of stuff goes on inside the Keychain & Security frameworks, and the CDSA itself, even for simple requests. If you get malloc errors or BAD_ACCESS faults, you might want to check over any code which uses this method 79 | 80 | NSData* NSDataFromDataNoCopy(const CSSM_DATA *data, BOOL freeWhenDone); 81 | 82 | BOOL OIDsAreEqual(const CSSM_OID *a, const CSSM_OID *b); 83 | 84 | /*! @function NSDataFromHumanNSString 85 | @abstract Converts a human-readable representation of some raw data (i.e. hex form) to the raw data form. 86 | @discussion This is the opposite operation to NSData's description method, and is entirely compatible and complimentary. It ignores all newlines, carriage returns, spaces, tabs, and angle-brackets ('<' and '>'). It is, of course, not case sensitive. 87 | @param string The string containing the human readable hex form, e.g. "<5d2f 5aa3>" or "0x836D" etc. 88 | @result nil if the string is not in a valid format, the resulting NSData otherwise. */ 89 | 90 | NSData* NSDataFromHumanNSString(NSString *string); 91 | -------------------------------------------------------------------------------- /Keychain/SKeyPlus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKeyPlus.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on 26/01/05. 6 | // Copyright 2005 Wade Tregaskis. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | 14 | @interface SKeyPlusGenerator : NSObject { 15 | CSSM_DATA base; 16 | unsigned int usesRemaining; 17 | 18 | CSSM_DATA current; 19 | } 20 | 21 | /*! @method generatorWithPassword:uses: 22 | @abstract Generates a new S/Key with a given base password and number of uses. 23 | @discussion The returned S/Key will be able to generate passwords from the sequence based on 'password', with up to 'uses' unique passwords generated. 24 | 25 | Note that unlike some other Keychain framework classes, this method will always return a new SKeyPlusGenerator instance, even if another one already exists with the same password & uses count. There are many situations where you may want two independant copies, since using them changes them. 26 | 27 | Also note that you do not have to call nextPassword before using the returned SKeyPlusGenerator - it is automatically initialised to the first password in sequence. 28 | @param password The base password to use. This will be copied and stored internally, and will never be revealed again. Make sure you keep your own copy if you don't want to lose it. 29 | @param uses The maximum number of uses permitted of the S/Key. This must be the same for all users of the S/Key (e.g. client & server), otherwise they will not be able to match up to each other, even with the same base password. You will not be able to retrieve this value from the returned instance, so make sure you keep a copy of it if necessary. 30 | @result Returns a new SKeyPlusGenerator instance if successful, nil if an error occurs. */ 31 | 32 | + (SKeyPlusGenerator*)generatorWithPassword:(NSString*)password uses:(unsigned int)uses; 33 | 34 | /*! @method initWithPassword:uses: 35 | @abstract Initialises a new S/Key with a given base password and number of uses. 36 | @discussion The returned S/Key will be able to generate passwords from the sequence based on 'password', with up to 'uses' unique passwords generated. You cannot call this method on an already initialised SKeyPlusGenerator instance - it will return nil, and leave the original unmodified. 37 | 38 | Note that unlike some other Keychain framework classes, this method will always return either nil or the receiver; it will not try to return any existing instance which may have the same initialisation parameters. SKeyPlusGenerator's are always considered unequal to each other (this includes when used with methods such as isEqual:). 39 | 40 | Also note that you do not have to call nextPassword before using the returned SKeyPlusGenerator - it is automatically initialised to the first password in sequence. 41 | @param password The base password to use. This will be copied and stored internally, and will never be revealed again. Make sure you keep your own copy if you don't want to lose it. 42 | @param uses The maximum number of uses permitted of the S/Key. This must be the same for all users of the S/Key (e.g. client & server), otherwise they will not be able to match up to each other, even with the same base password. You will not be able to retrieve this value from the returned instance (only the current number of uses remaining), so make sure you keep a copy of it if necessary. 43 | @result Returns the receiver if successful, nil if an error occurs. */ 44 | 45 | - (SKeyPlusGenerator*)initWithPassword:(NSString*)password uses:(unsigned int)uses; 46 | 47 | /*! @function usesRemaining 48 | @abstract Returns the number of uses remaining of the SKeyPlusGenerator. 49 | @discussion This number will always decrement over time, although is not guaranteed to change between calls (this method itself does not change the receiver). 50 | 51 | A return value of 0 indicates the receiver has expired and can no longer generate passwords. The 'currentPassword' and 'nextPassword' methods will logically return nil, in this case. 52 | 53 | Note that this number of uses includes the current password - i.e. a return value of 1 means the next call to nextPassword will not generate a new password, but rather nil as the receiver will have expired. 54 | @result Returns the number of uses remaining. */ 55 | 56 | - (unsigned int)usesRemaining; 57 | 58 | /*! @function currentPassword 59 | @abstract Returns the current password for the current number of uses remaining. 60 | @discussion See the description on how S/Key systems work for more details. 61 | 62 | This method will not change the receiver - that is, it will not decrement the number of uses count. You may call it any number of times and will receive the same password (provided of course you don't call nextPassword inbetween). 63 | @result Returns the current password, or nil if the receiver has expired. */ 64 | 65 | - (NSData*)currentPassword; 66 | 67 | /*! @function nextPassword 68 | @abstract Generates and returns the next password in the receiver's sequence. 69 | @discussion This method will change the receiver, and should only be called at appropriate times. It first decrements the number of uses remaining, and then generates the password for the new number of uses. It then returns the new password. 70 | 71 | If the number of uses remaining drops to 0, the receiver expires and nil will be returned. If the number of uses remaining is already 0 when this method is invoked, nil will be returned immediately. 72 | 73 | Note that you can retrieve the 'current' password - that is, the password returned by the most recent call to this method, using the currentPassword method. 74 | 75 | Also note that you do *not* have to call this method after initialisation - the class is automatically initialised to the first password in the sequence. 76 | @result Returns the next password in the sequence, or nil if the receiver has expired. */ 77 | 78 | - (NSData*)nextPassword; 79 | 80 | @end 81 | 82 | 83 | @interface SKeyPlusVerifier : NSObject { 84 | unsigned int usesRemaining; 85 | CSSM_DATA current; 86 | 87 | BOOL allowSkips; 88 | } 89 | 90 | + (SKeyPlusVerifier*)verifierWithCurrentPassword:(NSData*)currentPassword usesRemaining:(unsigned int)currentUsesRemaining; 91 | 92 | - (SKeyPlusVerifier*)initWithCurrentPassword:(NSData*)currentPassword usesRemaining:(unsigned int)currentUsesRemaining; 93 | 94 | - (void)setAllowsSkips:(BOOL)shouldAllowSkips; 95 | - (BOOL)allowsSkips; 96 | 97 | - (BOOL)verifyAgainst:(NSData*)password usesRemaining:(unsigned int)uses; 98 | - (BOOL)verifyAndUpdateAgainst:(NSData*)password usesRemaining:(unsigned int)uses; 99 | 100 | - (unsigned int)usesRemaining; 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /Keychain/CertificateBundle.m: -------------------------------------------------------------------------------- 1 | // 2 | // CertificateBundle.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sat Feb 01 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "CertificateBundle.h" 15 | 16 | 17 | @implementation CertificateBundle 18 | 19 | + (CertificateBundle*)certificateBundleWithCertificates:(NSArray*)certs { 20 | return [[self class] certificateBundleOfType:CSSM_CERT_BUNDLE_PGP_KEYRING withEncoding:CSSM_CERT_BUNDLE_ENCODING_PGP withCertificates:certs]; 21 | } 22 | 23 | + (CertificateBundle*)certificateBundleOfType:(CSSM_CERT_BUNDLE_TYPE)type withEncoding:(CSSM_CERT_BUNDLE_ENCODING)encoding withCertificates:(NSArray*)certs { 24 | return [[[[self class] alloc] initWithType:type withEncoding:encoding withCertificates:certs] autorelease]; 25 | } 26 | 27 | + (CertificateBundle*)certificateBundleWithBundle:(CSSM_CERT_BUNDLE_PTR)bun { 28 | return [[self class] certificateBundleWithBundle:bun releasingWhenDone:NO]; 29 | } 30 | 31 | + (CertificateBundle*)certificateBundleWithBundle:(CSSM_CERT_BUNDLE_PTR)bun releasingWhenDone:(BOOL)release { 32 | return [[[[self class] alloc] initWithBundle:bun releasingWhenDone:release] autorelease]; 33 | } 34 | 35 | - (CertificateBundle*)initWithCertificates:(NSArray*)certs { 36 | return [self initWithType:CSSM_CERT_BUNDLE_PGP_KEYRING withEncoding:CSSM_CERT_BUNDLE_ENCODING_PGP withCertificates:certs]; 37 | } 38 | 39 | - (CertificateBundle*)initWithType:(CSSM_CERT_BUNDLE_TYPE)type withEncoding:(CSSM_CERT_BUNDLE_ENCODING)encoding withCertificates:(NSArray*)certs { 40 | if (certs && (self = [super init])) { 41 | CFMutableArrayRef array; 42 | NSEnumerator *enumerator; 43 | id current; 44 | 45 | array = CFArrayCreateMutable(NULL, [certs count], NULL); 46 | 47 | if (array) { 48 | enumerator = [certs objectEnumerator]; 49 | 50 | while (current = [enumerator nextObject]) { 51 | if ([current isKindOfClass:[Certificate class]]) { 52 | CFArrayAppendValue(array, [current certificateRef]); 53 | } 54 | } 55 | 56 | bundle = malloc(sizeof(CSSM_CERT_BUNDLE)); 57 | releaseWhenDone = YES; 58 | 59 | error = SecCertifcateBundleExport(array, type, encoding, &(bundle->Bundle)); 60 | 61 | CFRelease(array); 62 | 63 | if (error == 0) { 64 | bundle->BundleHeader.BundleType = type; 65 | bundle->BundleHeader.BundleEncoding = encoding; 66 | 67 | return self; 68 | } else { 69 | [self release]; 70 | 71 | self = nil; 72 | } 73 | } else { 74 | [self release]; 75 | 76 | self = nil; 77 | } 78 | } 79 | 80 | return self; 81 | } 82 | 83 | - (CertificateBundle*)initWithBundle:(CSSM_CERT_BUNDLE_PTR)bun { 84 | return [self initWithBundle:bun releasingWhenDone:NO]; 85 | } 86 | 87 | - (CertificateBundle*)initWithBundle:(CSSM_CERT_BUNDLE_PTR)bun releasingWhenDone:(BOOL)release { 88 | if (bun && (self = [super init])) { 89 | releaseWhenDone = release; 90 | bundle = bun; 91 | } else { 92 | [self release]; 93 | self = nil; 94 | } 95 | 96 | return self; 97 | } 98 | 99 | - (CertificateBundle*)init { 100 | [self release]; 101 | return nil; 102 | } 103 | 104 | - (CSSM_CERT_BUNDLE_TYPE)type { 105 | return bundle->BundleHeader.BundleType; 106 | } 107 | 108 | - (BOOL)typeIsCustom { 109 | return ([self type] == CSSM_CERT_BUNDLE_CUSTOM); 110 | } 111 | 112 | - (BOOL)typeIsPKCS7 { 113 | return ([self type] == CSSM_CERT_BUNDLE_PKCS7_SIGNED_DATA); 114 | } 115 | 116 | - (BOOL)typeIsPKCS7Enveloped { 117 | return ([self type] == CSSM_CERT_BUNDLE_PKCS7_SIGNED_ENVELOPED_DATA); 118 | } 119 | 120 | - (BOOL)typeIsPKCS12 { 121 | return ([self type] == CSSM_CERT_BUNDLE_PKCS12); 122 | } 123 | 124 | - (BOOL)typeIsPFX { 125 | return ([self type] == CSSM_CERT_BUNDLE_PFX); 126 | } 127 | 128 | - (BOOL)typeIsSPKI { 129 | return ([self type] == CSSM_CERT_BUNDLE_SPKI_SEQUENCE); 130 | } 131 | 132 | - (BOOL)typeIsPGP { 133 | return ([self type] == CSSM_CERT_BUNDLE_PGP_KEYRING); 134 | } 135 | 136 | - (BOOL)typeIsUnknown { 137 | return ([self type] == CSSM_CERT_BUNDLE_UNKNOWN); 138 | } 139 | 140 | - (CSSM_CERT_BUNDLE_ENCODING)encoding { 141 | return bundle->BundleHeader.BundleEncoding; 142 | } 143 | 144 | - (BOOL)encodingIsCustom { 145 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_CUSTOM); 146 | } 147 | 148 | - (BOOL)encodingIsBER { 149 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_BER); 150 | } 151 | 152 | - (BOOL)encodingIsDER { 153 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_DER); 154 | } 155 | 156 | - (BOOL)encodingIsSEXPR { 157 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_SEXPR); 158 | } 159 | 160 | - (BOOL)encodingIsPGP { 161 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_PGP); 162 | } 163 | 164 | - (BOOL)encodingIsUnknown { 165 | return ([self encoding] == CSSM_CERT_BUNDLE_ENCODING_UNKNOWN); 166 | } 167 | 168 | - (int)lastError { 169 | return error; 170 | } 171 | 172 | - (CSSM_CERT_BUNDLE_PTR)bundle { 173 | return bundle; 174 | } 175 | 176 | - (void)dealloc { 177 | if (releaseWhenDone && bundle) { 178 | free(bundle); 179 | } 180 | 181 | [super dealloc]; 182 | } 183 | 184 | @end 185 | -------------------------------------------------------------------------------- /Keychain/ABPersonAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABPersonAdditions.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Nov 14 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | extern NSString* const kABCertificateProperty; // Certificate(s) (multi-data) - depreciated 20 | extern NSString* const kABCertificateRefProperty; // Certificate ref(s) (multi-date) 21 | extern NSString* const kABCertificateWorkLabel; // Home certificate 22 | extern NSString* const kABCertificateHomeLabel; // Work certificate 23 | extern NSString* const kABCertificatePortableLabel; // Portable certificate 24 | 25 | 26 | @interface ABPerson (ABPersonCertificateAdditions) 27 | 28 | /*! @method primaryCertificates 29 | @abstract Returns the certificate(s) designated as primary for the receiver. 30 | @discussion See the Address Book documentation for information regarding primary and non-primary attributes. 31 | 32 | This method works in two steps. In the first, it tries to locate certificates in the current user's default keychain(s) based on public key references stored in the Address Book (in the receiver). It then falls back to looking for any certificates actually embedded into the Address Book, for the receiver. This latter step is only for backwards compatibility and should not be used nor relied on. See the documentation for addRawCertificate:label:primary: for more information. 33 | 34 | If no primary is designated, or an error occurs, nil is returned. If there is only one entry, it is returned as the presumed primary. 35 | @result Nil if nothing found or an error occurs, otherwise an array of one or more certificates relating to the receiver. */ 36 | 37 | - (NSArray*)primaryCertificates; 38 | 39 | /*! @method certificates 40 | @abstract Returns all the certificate(s) for the receiver. 41 | @discussion This method works in two steps. In the first, it tries to locate certificates in the current user's default keychain(s) based on public key references stored in the Address Book (in the receiver). It then falls back to looking for any certificates actually embedded into the Address Book, for the receiver. This latter step is only for backwards compatibility and should not be used nor relied on. See the documentation for addRawCertificate:label:primary: for more information. 42 | @result Nil if nothing found or an error occurs, otherwise an array of one or more certificates relating to the receiver. */ 43 | 44 | - (NSArray*)certificates; 45 | 46 | /*! @method addRawCertificate: 47 | @abstract Adds a certificate to the receiver by embedding it in the Address Book. 48 | @discussion This method actually adds the given certificate into the Address Book, as raw data. It can thus be reliably retrieved at any point in time, as there are no further dependencies. However, this has the disadvantage that it fills the Address Book with large amounts of data, which is both unprotected and inaccessible to other security programs, whom may not use the Address Book. Thus, use of this method is depreciated - use the addCertificate:label:primary: method instead. 49 | @param certificate The certificate to add (embed). 50 | @param label The label to give to the entry. 51 | @param primary YES if the given certificate should be made the primary, NO otherwise. 52 | @result YES if the add was successful, NO otherwise. */ 53 | 54 | - (BOOL)addRawCertificate:(Certificate*)certificate label:(NSString*)label primary:(BOOL)primary; 55 | 56 | /*! @method addCertificate: 57 | @abstract Adds a certificate (by reference) the receiver. 58 | @discussion This method actually adds a reference to the public key in the given certificate, to the ultimate effect that the given certificate may be retrieved at some later date by matching the public key hashes. 59 | 60 | In end user terms, all you need do is call this method for each certificate you wish to add, and then make sure the certificate is available somewhere appropriate - e.g. in one of the current user's keychains. The primaryCertificates and certificates methods will then deal with the details with regards to locating these again. 61 | 62 | Note that because a reference to the public key is kept, not the particular certificate in itself, after adding just one certificate with a given public key, all certificates for that public key will then be returned by the relevant methods. This is considered a feature by design, since it makes sense on a practical level. If you have any concerns with this, submit a bug or feature request, detailing what you find improper about this behaviour. 63 | 64 | Also note that there is no problem with adding multiple certificates for the same public key. Only one reference to that particular public key will be added, as you would expect, and all adds will be successful. 65 | @param certificate The certificate to add (by reference). 66 | @param label The label to give to the given certificate. Note that this is actually the label for the public key, in a sense. If a public key reference already exists, but under a different label, then a new duplicate entry will be added with the given label. This makes sense, since your "Friends" and "Family" certificates, for example, might be the same, while you still reserve a separate set for "Work". 67 | @param primary YES if the given certificate should be made the primary for the receiver, NO otherwise. 68 | @result YES if the certificate was added successfully (or was effectively already there), NO otherwise. */ 69 | 70 | - (BOOL)addCertificate:(Certificate*)certificate label:(NSString*)label primary:(BOOL)primary; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Keychain/NSCachedObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSCachedObject.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Sun Feb 16 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | 16 | 17 | /*! @class NSCachedObject 18 | @abstract An extension of NSObject which allows for caching of subclass instances, such that only one unique instance of the subclass exists for any particular key object. 19 | @discussion This class provides a generic mechanism for ensuring uniqueness of subclasses which inherit from it. It maintains a list of cached objects, which can be queried when creating new objects to ensure duplicates don't spring into being. 20 | 21 | Note that this class has been rewritten since it's first conception, and is now both thread-safe and [relatively] efficient, compared with the original method. Performance is no largely subclass-independent, so one class which has many instances won't effect the perform of other subclasses. Performance within each subclass, however, is sadly still linear - don't try scaling this up too far. 22 | 23 | Please also note that I'm well aware of the NS prefix being an 'official', Apple-reserved one. I have two answers to this. First, I'm too lazy to change all the references to it given I have too much other stuff to do as it is. Secondly, I believe this class (or at least something with the same functionality) should be part of the Foundation framework, alongside NSObject. So I'm just using the NS prefix now to make it easier for Apple to copy and paste it in. ;) 24 | 25 | If someone from Apple takes offense to me using the prefix, they can contact me and I'll change it. Otherwise, things will be left well enough alone. */ 26 | 27 | @interface NSCachedObject : NSObject {} 28 | 29 | /*! @method instanceWithKey:from:simpleKey: 30 | @abstract Return an existing instance (if any) by matching the provided key with that returned by the provided selector. 31 | @discussion This method looks for an existing instance [of the same class as the receiver] which returns an identical key from the selector provided. If the simpleKey parameter is YES, keys are compared purely as memory addresses, despite being id's. This allows for the use of keys which are simply pointers or integers - both can be cast to id's, which are themselves simply void pointers. 32 | 33 | If the simpleKey parameter is NO, keys are compared using isEqual. Obviously this only works if the key actually is an object of some kind, inheriting from NSObject, or defining it's own isEqual method. 34 | 35 | If you need to use a more comprehensive comparison between keys, take a look at instanceForSelector:with. 36 | @param key The key to look for. If you're looking at creating a new instance, this key would be the same key you plan to give to your new instance. 37 | @param selector A selector which, when applied to a cached object, returns a key object. Note that if an object in the cache does not respond to the provided selector it is simply ignored - such a case is not considered an error. 38 | @param simpleKey If YES, keys are compared based solely on their address. If NO, isEqual is used. 39 | @result If an existing instance exists which returns a matching key, it is returned. Otherwise, or in case of error, nil is returned. */ 40 | 41 | + (id)instanceWithKey:(id)key from:(SEL)selector simpleKey:(BOOL)simpleKey; 42 | 43 | /*! @method instanceForSelector:with: 44 | @abstract Returns an existing instance (if any) by querying existing instances with the provided key. 45 | @discussion This method works in a similar way to instanceWithKey:from:simpleKey:, except that instead of using the provided selector to return an instance's key, it uses the selector to pass the key to an object, which can then return YES in the case of a match, or NO otherwise. This allows you to define your own methods for comparing keys, rather than using isEqual or address comparison. 46 | 47 | Note that if multiple instances will match a given key, only the first one found will be returned. At present, instances are checked in chronological order, starting with the oldest. This is not defined behavior, however, and may change in future. 48 | @param selector A selector which, when applied to a cached object along with the supplied key, returns a BOOL specifying whether that instance matches for that key. 49 | @param key A key. This may be a real object, or an integer/pointer cast to 'id' (i.e. a void pointer). 50 | @result Returns any existing instance which returns YES from the selector, otherwise - or in case of an error - returns nil. */ 51 | 52 | + (id)instanceForSelector:(SEL)selector with:(id)key; 53 | 54 | /*! @method init 55 | @abstract Adds the receiver to the global object cache. 56 | @discussion When called this method creates the global object cache, if it doesn't already exist, and adds the receiver to it. Consequently, you should always call this method for each new instance you create (using [super init] in your subclass). Otherwise the global object cache will be missing entries and may not function as expected. 57 | 58 | Note that this does not check if the receiver is already in the cache. You shouldn't be calling init on an already initialized instance anyway, and this method can't magically figure out what key the receiver has. Consequently, you must check for yourself if an instance for a given key already exists, prior to calling this method on your new instance. If you try checking after calling this method, you will obviously match the instance you just initialized, and the whole system breaks down. 59 | @result The receiver, or nil if an error occurs. */ 60 | 61 | - (id)init; 62 | 63 | /*! @method dealloc 64 | @abstract Removes the receiver from the global object cache. 65 | @discussion This should automatically be called when your object dies, so you wouldn't normally worry about it. It makes sure the receiver is removed from any object caches, if it is in any. If it didn't do this, you'd very quickly crash with lots of random memory errors, due the dangling pointers that would be lying around. */ 66 | 67 | - (void)dealloc; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Keychain/Identity.h: -------------------------------------------------------------------------------- 1 | // 2 | // Identity.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | /*! @class Identity 22 | @abstract Represents an entity via a certificate for that entity, and the corresponding private key of that entity. 23 | @discussion This isn't currently used for anything. I suspect there's something coming in a future version of the Security framework (possibly in Panther) which actually makes use of it. */ 24 | 25 | @interface Identity : NSCachedObject { 26 | SecIdentityRef identity; 27 | int error; 28 | } 29 | 30 | /*! @method identityWithIdentityRef: 31 | @abstract Creates and returns an Identity derived from the provided SecIdentityRef. 32 | @discussion This method caches each unique Identity instance, such that multiple calls to it with the same SecIdentityRef will return the same Identity instance. 33 | @param ident The SecIdentityRef from which to derive the returned instance. 34 | @result The existing instance, if one exists, or a newly created one otherwise. If an error occurs, nil is returned. */ 35 | 36 | + (Identity*)identityWithIdentityRef:(SecIdentityRef)ident; 37 | 38 | /*! @method identityWithCertificate:privateKey:inKeychain: 39 | @abstract Adds a new identity (composed of a certificate and associated private key) to a particular keychain, and returns the new Identity resulting from this addition. 40 | @discussion An Identity is tied to the particular keychain in which it's certificate and private key reside. Thus, an Identity cannot exist outside a keychain, and the same certificate and private key in two separate keychains will result in two separate Identity instance's, which are not considered in any way the same. You may wish to check for duplicates manually. 41 | 42 | Note that this method does not verify that the subject's public key and the given private key match. To do so may require performing some cryptographic operations, which may result in undesirable performance losses. However, it is considered a bug that it does not verify the pairing, and so the behavior may change in future. 43 | 44 | Also note that there is no equivelant instance initializer for this class constructor. This is because the Security framework currently requires such a silly way of adding Identities that the process would have to create a new instance anyway. Thus, there's little point having an instance initializer that always returns a new instance. 45 | @param certificate The certificate for the identity. This may be self-signed, or signed by some other person or authority. The subject's public key should correspond to the private key passed to this method. 46 | @param privateKey The private key corresponding to the subject's public key in the given certificate. 47 | @param keychain The keychain in which to create the new Identity. 48 | @param label A user-readable label given to the Identity, that will be displayed as the name of both the certificate and the identity itself (note: the private key's label is used internally for another purpose, and is not considered user-readable). 49 | @result If successfully created and added, the new Identity instance is returned. If an error occurs (e.g. the certificate and/or private key are already in the keychain) this method returns nil. */ 50 | 51 | + (Identity*)identityWithCertificate:(Certificate*)certificate privateKey:(Key*)privateKey inKeychain:(Keychain*)keychain label:(NSString*)label; 52 | 53 | /*! @method initWithIdentityRef: 54 | @abstract Initializes the receiver from the SecIdentityRef provided. 55 | @discussion This method keeps a cache of all unique Identity instances, so calling this a second time with the same SecIdentityRef will return the existing instance. The receiver retains a copy of the SecIdentityRef for the duration of it's life. 56 | @param ident The SecIdentityRef to initialize the receiver from. 57 | @result If an existing instance has the same SecIdentityRef, the receiver is released and the existing instance returned. Otherwise, the receiver is initialized from the SecIdentityRef provided. If an error occurs, nil is returned. */ 58 | 59 | - (Identity*)initWithIdentityRef:(SecIdentityRef)ident; 60 | 61 | /*! @method init 62 | @abstract Reject initialiser. 63 | @discussion You cannot initialise a Identity using "init" - use one of the other initialisation methods. 64 | @result This method always releases the receiver and returns nil. */ 65 | 66 | - (Identity*)init; 67 | 68 | /*! @method certificate 69 | @abstract Returns the certificate of the identity. 70 | @result The certificate for the receiver. */ 71 | 72 | - (Certificate*)certificate; 73 | 74 | /*! @method publicKey 75 | @abstract Returns the public key of the identity. 76 | @result The public key for the receiver. */ 77 | 78 | - (Key*)publicKey; 79 | 80 | /*! @method privateKey 81 | @abstract Returns the private key of the identity. 82 | @result The private key for the receiver. */ 83 | 84 | - (Key*)privateKey; 85 | 86 | /*! @method lastError 87 | @abstract Returns the last error that occured for the receiver. 88 | @discussion The set of error codes encompasses those returned by Sec* functions - refer to the Security framework documentation for a list. At present there are no other error codes defined for Access instances. 89 | 90 | Please note that this error code is local to the receiver only, and not any sort of shared global value. 91 | @result The last error that occured, or zero if the last operation was successful. */ 92 | 93 | - (int)lastError; 94 | 95 | /*! @method identityRef 96 | @abstract Returns a SecIdentityRef representing the receiver. 97 | @result A SecIdentityRef derived from the receiver, and linked to. Changes to the returned object will reflect in the receiver, and vice versa. */ 98 | 99 | - (SecIdentityRef)identityRef; 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /Keychain/CSSMInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMInfo.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Thu Jul 08 2004. 6 | // 7 | // Copyright (c) 2004, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | 15 | #import "CSSMInfo.h" 16 | 17 | #import 18 | 19 | 20 | NSString *USER_AUTHENTICATED = @"USER_AUTHENTICATED"; // True if the user has authenticated on the token 21 | 22 | NSString *TOKEN_WRITE_PROTECTED = @"TOKEN_WRITE_PROTECTED"; // Service provider is write protected 23 | NSString *TOKEN_LOGIN_REQUIRED = @"TOKEN_LOGIN_REQUIRED"; // User must login to access private objects. 24 | NSString *TOKEN_USER_PIN_INITIALIZED = @"TOKEN_USER_PIN_INITIALIZED"; // User's PIN has been initialized. 25 | NSString *TOKEN_PROT_AUTHENTICATION = @"TOKEN_PROT_AUTHENTICATION"; // Service provider has protected authentication path for entering a user PIN. No password should be supplied to the CSSM_CSP_Login API. 26 | NSString *TOKEN_USER_PIN_EXPIRED = @"TOKEN_USER_PIN_EXPIRED"; // The user PIN must be changed before the service provider can be used. 27 | NSString *TOKEN_SESSION_KEY_PASSWORD = @"TOKEN_SESSION_KEY_PASSWORD"; // Session keys held by the CSP require individual passwords, possibly in addition to a login password. 28 | NSString *TOKEN_PRIVATE_KEY_PASSWORD = @"TOKEN_PRIVATE_KEY_PASSWORD"; // Private keys held by the CSP require individual passwords, possibly in addition to a login password 29 | NSString *TOKEN_STORES_PRIVATE_KEYS = @"TOKEN_STORES_PRIVATE_KEYS"; // CSP can store private keys. 30 | NSString *TOKEN_STORES_PUBLIC_KEYS = @"TOKEN_STORES_PUBLIC_KEYS"; // CSP can store public keys. 31 | NSString *TOKEN_STORES_SESSION_KEYS = @"TOKEN_STORES_SESSION_KEYS"; // CSP can store session/secret keys 32 | NSString *TOKEN_STORES_CERTIFICATES = @"TOKEN_STORES_CERTIFICATES"; // Service provider can store certs using DL APIs. 33 | NSString *TOKEN_STORES_GENERIC = @"TOKEN_STORES_GENERIC"; // Service provider can store generic objects using DL APIs. 34 | 35 | NSString *MAX_SESSION_COUNT = @"MAX_SESSION_COUNT"; // Maximum number of CSP handles referencing the token that may exist simultaneously. 36 | NSString *OPEN_SESSION_COUNT = @"OPEN_SESSION_COUNT"; // Number of existing CSP handles referencing the token. 37 | NSString *MAX_RW_SESSION_COUNT = @"MAX_RW_SESSION_COUNT"; // Maximum number of CSP handles that can reference the token simultaneously in read-write mode. 38 | NSString *OPEN_RW_SESSION_COUNT = @"OPEN_RW_SESSION_COUNT"; // Number of existing CSP handles referencing the token in read-write mode. 39 | NSString *TOTAL_PUBLIC_MEMORY = @"TOTAL_PUBLIC_MEMORY"; // Amount of public storage space in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 40 | NSString *FREE_PUBLIC_MEMORY = @"FREE_PUBLIC_MEMORY"; // Amount of public storage space available for use in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 41 | NSString *TOTAL_PRIVATE_MEMORY = @"TOTAL_PRIVATE_MEMORY"; // Amount of private storage space in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 42 | NSString *FREE_PRIVATE_MEMORY = @"FREE_PRIVATE_MEMORY"; // Amount of private storage space available for use in the CSP. This value will be set to CSSM_VALUE_NOT_AVAILABLE if the CSP does not wish to expose this information. 43 | 44 | 45 | NSDictionary* cssmOperatingStatistics(CSSM_CSP_HANDLE handle) { 46 | CSSM_CSP_OPERATIONAL_STATISTICS statistics; 47 | NSMutableDictionary *result = nil; 48 | 49 | if (CSSM_OK == CSSM_CSP_GetOperationalStatistics((handle != 0) ? handle : keychainFrameworkCSPHandle(), &statistics)) { 50 | result = [NSMutableDictionary dictionaryWithCapacity:10]; 51 | 52 | [result setObject:[NSNumber numberWithBool:statistics.UserAuthenticated] forKey:USER_AUTHENTICATED]; 53 | 54 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_WRITE_PROTECTED)] forKey:TOKEN_WRITE_PROTECTED]; 55 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_LOGIN_REQUIRED)] forKey:TOKEN_LOGIN_REQUIRED]; 56 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_USER_PIN_INITIALIZED)] forKey:TOKEN_USER_PIN_INITIALIZED]; 57 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_PROT_AUTHENTICATION)] forKey:TOKEN_PROT_AUTHENTICATION]; 58 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_USER_PIN_EXPIRED)] forKey:TOKEN_USER_PIN_EXPIRED]; 59 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_SESSION_KEY_PASSWORD)] forKey:TOKEN_SESSION_KEY_PASSWORD]; 60 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_TOK_PRIVATE_KEY_PASSWORD)] forKey:TOKEN_PRIVATE_KEY_PASSWORD]; 61 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_STORES_PRIVATE_KEYS)] forKey:TOKEN_STORES_PRIVATE_KEYS]; 62 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_STORES_PUBLIC_KEYS)] forKey:TOKEN_STORES_PUBLIC_KEYS]; 63 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_STORES_SESSION_KEYS)] forKey:TOKEN_STORES_SESSION_KEYS]; 64 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_STORES_CERTIFICATES)] forKey:TOKEN_STORES_CERTIFICATES]; 65 | [result setObject:[NSNumber numberWithBool:(statistics.DeviceFlags & CSSM_CSP_STORES_GENERIC)] forKey:TOKEN_STORES_GENERIC]; 66 | 67 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenMaxSessionCount] forKey:MAX_SESSION_COUNT]; 68 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenOpenedSessionCount] forKey:OPEN_SESSION_COUNT]; 69 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenMaxRWSessionCount] forKey:MAX_RW_SESSION_COUNT]; 70 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenOpenedRWSessionCount] forKey:OPEN_RW_SESSION_COUNT]; 71 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenTotalPublicMem] forKey:TOTAL_PUBLIC_MEMORY]; 72 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenFreePublicMem] forKey:FREE_PUBLIC_MEMORY]; 73 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenTotalPrivateMem] forKey:TOTAL_PRIVATE_MEMORY]; 74 | [result setObject:[NSNumber numberWithUnsignedInt:statistics.TokenFreePrivateMem] forKey:FREE_PRIVATE_MEMORY]; 75 | } 76 | 77 | return result; 78 | } 79 | -------------------------------------------------------------------------------- /Keychain/Access.m: -------------------------------------------------------------------------------- 1 | // 2 | // Access.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Fri Jan 24 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "Access.h" 15 | 16 | 17 | @implementation Access 18 | 19 | + (Access*)accessWithName:(NSString*)name { 20 | return [[[[self class] alloc] initWithName:name applications:nil] autorelease]; 21 | } 22 | 23 | + (Access*)accessWithName:(NSString*)name applications:(NSArray*)apps { 24 | return [[[[self class] alloc] initWithName:name applications:apps] autorelease]; 25 | } 26 | 27 | + (Access*)accessWithAccessRef:(SecAccessRef)acc { 28 | return [[[[self class] alloc] initWithAccessRef:acc] autorelease]; 29 | } 30 | 31 | - (Access*)initWithName:(NSString*)name applications:(NSArray*)apps { 32 | if (self = [super init]) { 33 | CFMutableArrayRef convertedArray = NULL; 34 | CFTypeID trustedApplicationType = SecTrustedApplicationGetTypeID(); 35 | 36 | if (apps) { 37 | convertedArray = CFArrayCreateMutable(NULL, 0, NULL); 38 | 39 | if (convertedArray) { 40 | NSEnumerator *enumerator = [apps objectEnumerator]; 41 | id current; 42 | 43 | while (current = [enumerator nextObject]) { 44 | if ([current isKindOfClass:[TrustedApplication class]]) { 45 | CFArrayAppendValue(convertedArray, [current trustedApplicationRef]); 46 | } else if (CFGetTypeID(current) == trustedApplicationType) { 47 | CFArrayAppendValue(convertedArray, current); 48 | } 49 | } 50 | } else { 51 | return nil; 52 | } 53 | } 54 | 55 | error = SecAccessCreate((CFStringRef)name, convertedArray, &access); // Don't know whether name is permitted to be NULL, so make no assumptions 56 | 57 | if (convertedArray) { 58 | CFRelease(convertedArray); 59 | } 60 | 61 | return self; 62 | } else { 63 | [self release]; 64 | 65 | return nil; 66 | } 67 | } 68 | 69 | - (Access*)initWithAccessRef:(SecAccessRef)acc { 70 | if (acc && (self = [super init])) { 71 | Access *existingObject; 72 | 73 | existingObject = [[self class] instanceWithKey:(id)acc from:@selector(accessRef) simpleKey:NO]; 74 | 75 | if (existingObject) { 76 | [self release]; 77 | 78 | return [existingObject retain]; 79 | } else { 80 | CFRetain(acc); 81 | access = acc; 82 | 83 | return self; 84 | } 85 | } else { 86 | [self release]; 87 | 88 | return nil; 89 | } 90 | } 91 | 92 | - (Access*)init { 93 | return [self initWithName:@"Unnamed" applications:NULL]; 94 | } 95 | 96 | - (NSArray*)accessControlLists { 97 | CFArrayRef results; 98 | NSMutableArray *finalResults = nil; 99 | NSEnumerator *enumerator; 100 | SecACLRef current; 101 | 102 | error = SecAccessCopyACLList(access, &results); 103 | 104 | if ((error == 0) && results) { 105 | enumerator = [(NSArray*)results objectEnumerator]; 106 | finalResults = [NSMutableArray arrayWithCapacity:CFArrayGetCount(results)]; 107 | 108 | while (current = (SecACLRef)[enumerator nextObject]) { 109 | [finalResults addObject:[AccessControlList accessControlListWithACLRef:current]]; 110 | } 111 | 112 | CFRelease(results); 113 | } 114 | 115 | return finalResults; 116 | } 117 | 118 | - (NSArray*)accessControlListsForAction:(CSSM_ACL_AUTHORIZATION_TAG)action { 119 | CFArrayRef results; 120 | NSMutableArray *finalResults = nil; 121 | NSEnumerator *enumerator; 122 | SecACLRef current; 123 | 124 | error = SecAccessCopySelectedACLList(access, action, &results); 125 | 126 | if ((error == 0) && results) { 127 | enumerator = [(NSArray*)results objectEnumerator]; 128 | finalResults = [NSMutableArray arrayWithCapacity:CFArrayGetCount(results)]; 129 | 130 | while (current = (SecACLRef)[enumerator nextObject]) { 131 | [finalResults addObject:[AccessControlList accessControlListWithACLRef:current]]; 132 | } 133 | 134 | CFRelease(results); 135 | } 136 | 137 | return finalResults; 138 | } 139 | 140 | - (NSArray*)accessControlListsForEverything { 141 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_ANY]; 142 | } 143 | 144 | - (NSArray*)accessControlListsForLogin { 145 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_LOGIN]; 146 | } 147 | 148 | - (NSArray*)accessControlListsForGeneratingKeys { 149 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_GENKEY]; 150 | } 151 | 152 | - (NSArray*)accessControlListsForDeletion { 153 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_DELETE]; 154 | } 155 | 156 | - (NSArray*)accessControlListsForExportingWrapped { 157 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED]; 158 | } 159 | 160 | - (NSArray*)accessControlListsForExportingClear { 161 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR]; 162 | } 163 | 164 | - (NSArray*)accessControlListsForImportingWrapped { 165 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_IMPORT_WRAPPED]; 166 | } 167 | 168 | - (NSArray*)accessControlListsForImportingClear { 169 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_IMPORT_CLEAR]; 170 | } 171 | 172 | - (NSArray*)accessControlListsForSigning { 173 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_SIGN]; 174 | } 175 | 176 | - (NSArray*)accessControlListsForEncrypting { 177 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_ENCRYPT]; 178 | } 179 | 180 | - (NSArray*)accessControlListsForDecrypting { 181 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_DECRYPT]; 182 | } 183 | 184 | - (NSArray*)accessControlListsForMACGeneration { 185 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_MAC]; 186 | } 187 | 188 | - (NSArray*)accessControlListsForDerivingKeys { 189 | return [self accessControlListsForAction:CSSM_ACL_AUTHORIZATION_DERIVE]; 190 | } 191 | 192 | - (int)lastError { 193 | return error; 194 | } 195 | 196 | - (SecAccessRef)accessRef { 197 | return access; 198 | } 199 | 200 | - (void)dealloc { 201 | if (access) { 202 | CFRelease(access); 203 | } 204 | 205 | [super dealloc]; 206 | } 207 | 208 | @end 209 | -------------------------------------------------------------------------------- /Keychain/Trust.m: -------------------------------------------------------------------------------- 1 | // 2 | // Trust.m 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed Feb 05 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import "Trust.h" 15 | 16 | #import 17 | 18 | 19 | @implementation Trust 20 | 21 | + (SecTrustUserSetting)userTrustForCeritifcate:(Certificate*)cert policy:(Policy*)pol { 22 | int err; 23 | SecTrustUserSetting result; 24 | 25 | err = SecTrustGetUserTrust([cert certificateRef], [pol policyRef], &result); 26 | 27 | if (err == 0) { 28 | return result; 29 | } else { 30 | return -1; 31 | } 32 | } 33 | 34 | + (void)setUserTrustForCertificate:(Certificate*)cert policy:(Policy*)pol trust:(SecTrustUserSetting)tru { 35 | SecTrustSetUserTrust([cert certificateRef], [pol policyRef], tru); 36 | } 37 | 38 | + (Trust*)trustForCertificates:(NSArray*)certificates policies:(NSArray*)policies { 39 | return [[[[self class] alloc] initForCertificates:certificates policies:policies] autorelease]; 40 | } 41 | 42 | + (Trust*)trustWithTrustRef:(SecTrustRef)tru { 43 | return [[[[self class] alloc] initWithTrustRef:tru] autorelease]; 44 | } 45 | 46 | - (Trust*)initForCertificates:(NSArray*)certificates policies:(NSArray*)policies { 47 | CFMutableArrayRef certs, pols; 48 | NSEnumerator *enumerator; 49 | id current; 50 | 51 | certs = CFArrayCreateMutable(NULL, [certificates count], NULL); 52 | pols = CFArrayCreateMutable(NULL, [policies count], NULL); 53 | 54 | if (certs && pols) { 55 | enumerator = [certificates objectEnumerator]; 56 | 57 | while (current = [enumerator nextObject]) { 58 | if ([current isKindOfClass:[Certificate class]]) { 59 | CFArrayAppendValue(certs, [current certificateRef]); 60 | } 61 | } 62 | 63 | enumerator = [policies objectEnumerator]; 64 | 65 | while (current = [enumerator nextObject]) { 66 | if ([current isKindOfClass:[Policy class]]) { 67 | CFArrayAppendValue(pols, [current policyRef]); 68 | } 69 | } 70 | 71 | error = SecTrustCreateWithCertificates(certs, pols, &trust); 72 | 73 | CFRelease(certs); 74 | CFRelease(pols); 75 | 76 | if (error == 0) { 77 | self = [super init]; 78 | 79 | return self; 80 | } else { 81 | [self release]; 82 | 83 | return nil; 84 | } 85 | } else { 86 | return nil; 87 | } 88 | } 89 | 90 | - (Trust*)initWithTrustRef:(SecTrustRef)tru { 91 | Trust *existingObject; 92 | 93 | if (tru) { 94 | existingObject = [[self class] instanceWithKey:(id)tru from:@selector(trustRef) simpleKey:NO]; 95 | 96 | if (existingObject) { 97 | [self release]; 98 | 99 | return [existingObject retain]; 100 | } else { 101 | if (self = [super init]) { 102 | CFRetain(tru); 103 | trust = tru; 104 | } 105 | 106 | return self; 107 | } 108 | } else { 109 | [self release]; 110 | 111 | return nil; 112 | } 113 | } 114 | 115 | - (Trust*)init { 116 | [self release]; 117 | return nil; 118 | } 119 | 120 | - (void)makeTrustForKeychains:(NSArray*)chains { 121 | CFMutableArrayRef keychains; 122 | NSEnumerator *enumerator = [chains objectEnumerator]; 123 | id current; 124 | CFTypeID keychainType = SecKeychainGetTypeID(); 125 | 126 | keychains = CFArrayCreateMutable(NULL, [chains count], NULL); 127 | 128 | if (keychains) { 129 | while (current = [enumerator nextObject]) { 130 | if ([current isKindOfClass:[Keychain class]]) { 131 | CFArrayAppendValue(keychains, [current keychainRef]); 132 | } else if (CFGetTypeID(current) == keychainType) { 133 | CFArrayAppendValue(keychains, current); 134 | } 135 | } 136 | 137 | error = SecTrustSetKeychains(trust, keychains); 138 | 139 | CFRelease(keychains); 140 | } 141 | } 142 | 143 | - (void)allowExpiredCertificates:(BOOL)allow { 144 | uint8_t *result = malloc(sizeof(BOOL)); 145 | CFDataRef temp; 146 | 147 | if (result) { 148 | *result = allow; 149 | 150 | temp = CFDataCreate(NULL, result, sizeof(BOOL)); 151 | 152 | if (temp) { 153 | error = SecTrustSetParameters(trust, CSSM_TP_ACTION_ALLOW_EXPIRED, temp); 154 | 155 | free(result); 156 | CFRelease(temp); 157 | } 158 | } 159 | } 160 | 161 | - (BOOL)canEvaluate { 162 | error = SecTrustEvaluate(trust, &lastEval); 163 | 164 | return (error == 0); 165 | } 166 | 167 | - (BOOL)isInvalid { 168 | if (!lastEval) { 169 | if (![self canEvaluate]) { 170 | return YES; 171 | } 172 | } 173 | 174 | return (lastEval == kSecTrustResultInvalid); 175 | } 176 | 177 | - (BOOL)canProceed { 178 | if (!lastEval) { 179 | if (![self canEvaluate]) { 180 | return NO; 181 | } 182 | } 183 | 184 | return (lastEval == kSecTrustResultProceed); 185 | } 186 | 187 | - (BOOL)needsConfirmation { 188 | if (!lastEval) { 189 | if (![self canEvaluate]) { 190 | return NO; 191 | } 192 | } 193 | 194 | return (lastEval == kSecTrustResultConfirm); 195 | } 196 | 197 | - (BOOL)userDenied { 198 | if (!lastEval) { 199 | if (![self canEvaluate]) { 200 | return NO; 201 | } 202 | } 203 | 204 | return (lastEval == kSecTrustResultDeny); 205 | } 206 | 207 | - (BOOL)userDidNotSpecify { 208 | if (!lastEval) { 209 | if (![self canEvaluate]) { 210 | return NO; 211 | } 212 | } 213 | 214 | return (lastEval == kSecTrustResultUnspecified); 215 | } 216 | 217 | - (BOOL)hasRecoverableFailure { 218 | if (!lastEval) { 219 | if (![self canEvaluate]) { 220 | return YES; 221 | } 222 | } 223 | 224 | return (lastEval == kSecTrustResultRecoverableTrustFailure); 225 | } 226 | 227 | - (BOOL)hasFatalFailure { 228 | if (!lastEval) { 229 | if (![self canEvaluate]) { 230 | return NO; 231 | } 232 | } 233 | 234 | return (lastEval == kSecTrustResultFatalTrustFailure); 235 | } 236 | 237 | - (BOOL)hasUnknownError { 238 | if (!lastEval) { 239 | if (![self canEvaluate]) { 240 | return NO; 241 | } 242 | } 243 | 244 | return (lastEval == kSecTrustResultOtherError); 245 | } 246 | 247 | - (int)lastError { 248 | return error; 249 | } 250 | 251 | - (SecTrustRef)trustRef { 252 | return trust; 253 | } 254 | 255 | - (void)dealloc { 256 | if (trust) { 257 | CFRelease(trust); 258 | } 259 | 260 | [super dealloc]; 261 | } 262 | 263 | @end 264 | -------------------------------------------------------------------------------- /Keychain/CSSMUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMUtils.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Thu Mar 13 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | #import 16 | 17 | 18 | /*! @function GUIDAsString 19 | @abstract Returns a CSSM GUID in human-readable string form. 20 | @discussion The exact format of the string returned is not strictly defined, but in general terms is the hex form of the GUID, possibly broken up into several words. 21 | @param GUID The GUID to render in string form. 22 | @result Returns the given GUID in string form. */ 23 | 24 | NSString* GUIDAsString(CSSM_GUID GUID); 25 | 26 | /*! @function nameOfCertificateType 27 | @abstract Returns the human-readable name of a given certificate type. 28 | @discussion The names returned are simple, short & human-readable. e.g. the type CSSM_CERT_PGP returns "PGP". The names are localised. 29 | @param certificateType The type to name as a string. 30 | @result Returns the name of the given type, or (localised) "Unknown" if an unknown type is provided. */ 31 | 32 | NSString* nameOfCertificateType(CSSM_CERT_TYPE certificateType); 33 | 34 | /*! @function nameOfCertificateEncoding 35 | @abstract Returns the human-readable name of a given certificate encoding. 36 | @discussion The names returned are simple, short & human-readable. e.g. the type CSSM_CERT_ENCODING_BER returns "BER". The names are localised. 37 | @param certificateEncoding The encoding to name as a string. 38 | @result Returns the name of the given encoding, or (localised) "Unknown" if an unknown encoding is provided. */ 39 | 40 | NSString* nameOfCertificateEncoding(CSSM_CERT_ENCODING certificateEncoding); 41 | 42 | /*! @function nameOfBERCode 43 | @abstract Returns the human-readable name for a given BER code (or tag, if you like). 44 | @discussion The names returned are simple, short & human-readable. e.g. the type BER_TAG_INTEGER returns "Integer". The names are localised. 45 | @param tag The BER code to name as a string. 46 | @result Returns the name of the given BER code, or (localised) "Unknown" if an unknown encoding is provided. */ 47 | 48 | NSString* nameOfBERCode(CSSM_BER_TAG tag); 49 | 50 | /*! @function stringRepresentationOfBEREncodedData 51 | @abstract Returns a human-readable representation of some given data of a given BER type. 52 | @discussion This method is a bit kludgy - it makes a best-effort guess as to what format the data is, based on the tag, and renders it in a form which should be generally suitable. Ideally you should develop your own custom string rendering for BER data, to better suite your particular use. 53 | @param dat The data to render. Should not be NULL. 54 | @param tag The BER tag indicating what type 'dat' is. 55 | @result Returns some appropriate representation where possible, a raw hex dump for unknown types. Returns nil if an error occurs (e.g. 'dat' is NULL). */ 56 | 57 | NSString* stringRepresentationOfBEREncodedData(const CSSM_DATA *dat, CSSM_BER_TAG tag); 58 | 59 | /*! @function nameOfOIDType 60 | @abstract Returns a localized, human-readable name of a given OID. 61 | @discussion If a name cannot be found for the given OID, it is returned as a hex string. 62 | @param type The OID to name. 63 | @result Returns the localized name of the OID, or if a name cannot be found a hex string of the OID's raw data. Returns nil if an error occurs. */ 64 | 65 | NSString* nameOfOIDType(const CSSM_OID *type); 66 | 67 | /*! @function CSSMDateForCalendarDate 68 | @abstract Returns the CSSM_DATE represenation of a given NSCalendarDate. 69 | @discussion Trivial conversion between NSCalendarDate and CSSM_DATE. Note that the range of an NSCalendarDate is greater than that of a CSSM_DATE (which is limited to 0AD-9999AD (inclusive). If the given date cannot be represented as a CSSM_DATE, the result returned will be nullified (i.e. every byte set to 0). 70 | @param date The date to represent as a CSSM_DATE. Should not be nil. 71 | @result Returns the given date as a CSSM_DATE, or a nullified (all bytes set to zero) result if an error occurs (e.g. 'date' was nil, or outside the range representable by CSSM_DATE, etc). */ 72 | 73 | CSSM_DATE CSSMDateForCalendarDate(NSCalendarDate *date); 74 | 75 | /*! @function calendarDateForCSSMDate 76 | @abstract Returns the NSCalendarDate representation of a given CSSM_DATE. 77 | @discussion Trivial conversion between a CSSM_DATE and an NSCalendarDate. Since the range of NSCalendarDate is greater than that of CSSM_DATE, there should not be any mapping issues as there are for the CSSMDateForCalendarDate function. 78 | 79 | Note the degree of sanity checking performed by this function is not guaranteed - if you pass a date which purports to be the 35th day of the 27th month or somesuch, there is no guarantee this function will return an appropriate result (i.e. nil) - it may return a non-nil result who's value is undefined. 80 | @param date The date to convert. Should not be nil. 81 | @result Returns an appropriate NSCalendarDate, or nil if an error occurs (such as 'date' being NULL, or otherwise invalid). */ 82 | 83 | NSCalendarDate* calendarDateForCSSMDate(const CSSM_DATE *date); 84 | 85 | /*! @function calendarDateForTime 86 | @abstract Returns the NSCalendarDate representation of a given CSSM_X509_TIME. 87 | @discussion TODO - but note that the present implementation is NOT THREAD SAFE; it changes the NSTimeZone settings temporarily. 88 | @param time The time to convert. Should not be NULL. 89 | @result Returns an NSCalendarDate representing the given time, or nil if an error occurs. */ 90 | 91 | NSCalendarDate* calendarDateForTime(const CSSM_X509_TIME *time); 92 | void copyNSCalendarDateToTime(NSCalendarDate *date, CSSM_X509_TIME *time, CSSM_BER_TAG format); 93 | 94 | NSString* nameOfKeyBlob(CSSM_KEYBLOB_TYPE type); 95 | NSString* nameOfTypedFormat(CSSM_KEYBLOB_FORMAT format, CSSM_KEYBLOB_TYPE type); 96 | NSString* nameOfAlgorithm(CSSM_ALGORITHMS algo); 97 | NSString* nameOfKeyClass(CSSM_KEYCLASS class); 98 | NSString* nameOfAlgorithmMode(CSSM_ENCRYPT_MODE mode); 99 | 100 | NSString* namesOfAttributes(CSSM_KEYATTR_FLAGS attr); 101 | NSString* namesOfUsages(CSSM_KEYUSE use); 102 | 103 | NSString* subjectPublicKeyAsString(const CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *key); 104 | NSString* signatureAsString(const CSSM_X509_SIGNATURE *sig); 105 | 106 | NSString* x509NameAsString(const CSSM_X509_NAME *name); 107 | NSString* nameOfOIDAlgorithm(const CSSM_OID *oid); 108 | 109 | NSString* nameOfDataFormat(CSSM_X509EXT_DATA_FORMAT format); 110 | 111 | NSString* x509AlgorithmAsString(const CSSM_X509_ALGORITHM_IDENTIFIER *algo); 112 | NSString* nameOfOIDAttribute(const CSSM_OID *oid); 113 | 114 | NSString* nameOfOIDExtension(const CSSM_OID *oid); 115 | NSString* extensionAsString(const CSSM_X509_EXTENSION *ext); 116 | NSString* extensionsAsString(const CSSM_X509_EXTENSIONS *ext); 117 | 118 | void intToDER(uint32 theInt, CSSM_DATA *data); 119 | uint32 DERToInt(const CSSM_DATA *data); 120 | NSData* NSDataForDERFormattedInteger(uint32 value); 121 | -------------------------------------------------------------------------------- /Keychain/CSSMDefaults.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSSMDefaults.h 3 | // Keychain 4 | // 5 | // Created by Wade Tregaskis on Wed May 07 2003. 6 | // 7 | // Copyright (c) 2003, Wade Tregaskis. All rights reserved. 8 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | // * Neither the name of Wade Tregaskis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | #import 15 | 16 | 17 | /*! @constant DEFAULT_RANDOM_ALGORITHM 18 | @abstract The default random number generation algorithm used by the Keychain framework. 19 | @discussion The Keychain framework may require the use of a random number generator at numerous points, often without explicit indication of this (e.g. when generating init vectors, keys, or similar data). The algorithm used by the framework is indicated by this constant. This value may change in future versions of the framework. */ 20 | 21 | #define DEFAULT_RANDOM_ALGORITHM CSSM_ALGID_APPLE_YARROW 22 | 23 | /*! @constant RAW_KEY_VERSION_CURRENT 24 | @abstract Returns the current (latest) raw key format supported by the framework. 25 | @discussion This constant resolves to the newest version of the framework's proprietary raw key format. The framework is guaranteed to be able to read raw keys in all versions up to and including this version. By default it will generate raw keys in the latest format - there is at time of writing no way to explicitly choose a particular version. 26 | 27 | Note that use of the framework's proprietary format is not recommended, and may be obsoleted in a future version. */ 28 | 29 | #define RAW_KEY_VERSION_CURRENT RAW_KEY_VERSION_1 30 | 31 | /*! @constant KEYHEADER_VERSION_CURRENT_SIZE 32 | @abstract The header size of the current (latest) raw key format supported by the framework. 33 | @discussion This constant resolves to the size of the header (i.e. metadata, not key data itself) of the latest version of the Keychain framework's proprietary raw key format. The version it corresponds to is given by RAW_KEY_VERSION_CURRENT. 34 | 35 | Note that use of the framework's proprietary format is not recommended, and may be obsoleted in a future version. */ 36 | 37 | #define KEYHEADER_VERSION_CURRENT_SIZE KEYHEADER_VERSION_1_SIZE 38 | 39 | 40 | /*! @var keychainFrameworkInitVector 41 | @abstract A generic 16-byte init vector for cryptographic operations. 42 | @discussion You should avoid using this vector where possible - it is a legacy item that is due for removal in the near future. 43 | 44 | Note that you should not rely on this being constant, or containing the same data as keychainFrameworkInitVectorData. */ 45 | 46 | extern uint8 keychainFrameworkInitVector[16]; 47 | 48 | /*! @constant keychainFrameworkInitVectorData 49 | @abstract A generic init vector for cryptographic operations. 50 | @discussion You should avoid using this vector where possible - it is a legacy item that is due for removal in the near future. 51 | 52 | Note that you should not rely on this being constant, or containing the same data as keychainFrameworkInitVector. Nor should you assume a particular length - use the Length member to determine this. */ 53 | 54 | extern const CSSM_DATA keychainFrameworkInitVectorData; 55 | 56 | /*! @constant RAW_KEY_VERSION_1 57 | @abstract A constant representing version 1 of the proprietary Keychain raw key format (used by the 'key' extension of NSData, and the corresponding 'data' method of Key). 58 | @discussion The proprietary format used by the Keychain framework is not recommended for general purpose use. Nonetheless, it does support versioning in case it needs to be updated or extended in future. You shouldn't ever really need to use this constant, although you may find it useful to compare it with RAW_KEY_VERSION_CURRENT if you are looking for specific version support. */ 59 | 60 | extern const uint32 RAW_KEY_VERSION_1; 61 | 62 | /*! @constant KEYHEADER_VERSION_1_SIZE 63 | @abstract The size of a raw key header in the Keychain framework's proprietary format (version 1). 64 | @discussion The proprietary format used by the Keychain framework is not recommended for general purpose use. If you must use it, you may use this constant to determine the expected size of a raw key header (i.e. the key metadata, not including the actual key itself, which varies in length for different key types and strengths). */ 65 | 66 | extern const uint32 KEYHEADER_VERSION_1_SIZE; 67 | 68 | 69 | /*! @function defaultModeForAlgorithm 70 | @abstract Returns the default encryption mode for a given algorithm. 71 | @discussion This function returns a safe default mode for a particular algorithm, and is used automatically by the Keychain framework when necessary. For example, for any AES cryptographic operations, the framework will use this function to determine that the mode should be CSSM_ALGMODE_CBCPadIV8 (at time of writing). 72 | 73 | At time of writing there is no way to override these defaults, neither here nor on a per-operation basis. If you require such functionality, submit a feature request to the author or on Sourceforge (http://www.sourceforge.net/projects/keychain/) to voice your interest. 74 | @param algorithm The algorithm. Note that not all algorithms are known or supported, in which case CSSM_ALGMODE_NONE is returned. 75 | @result Returns a [hopefully] appropriate default mode for the given algorithm, or CSSM_ALGMODE_NONE if the algorithm is not explicitly supported. */ 76 | 77 | CSSM_ENCRYPT_MODE defaultModeForAlgorithm(CSSM_ALGORITHMS algorithm); 78 | 79 | /*! @function defaultPaddingForAlgorithm 80 | @abstract Returns the default padding mode for a given algorithm. 81 | @discussion This function returns a safe default padding mode for a particular algorithm, and is used automatically by the Keychain framework when necessary. For example, for any AES cryptographic operations, the framework will use this function to determine that the mode should be CSSM_PADDING_PKCS7 (at time of writing). 82 | 83 | At time of writing there is no way to override these defaults, neither here nor on a per-operation basis. If you require such functionality, submit a feature request to the author or on Sourceforge (http://www.sourceforge.net/projects/keychain/) to voice your interest. 84 | @param algorithm The algorithm. Note that not all algorithms are known or supported, in which case CSSM_PADDING_NONE is returned. 85 | @result Returns a [hopefully] appropriate default padding mode for the given algorithm, or CSSM_PADDING_NONE if the algorithm is not explicitly supported. */ 86 | 87 | CSSM_PADDING defaultPaddingForAlgorithm(CSSM_ALGORITHMS algorithm); 88 | 89 | /*! @function defaultDigestForAlgorithm 90 | @abstract Returns the default digest algorithm for a given algorithm. 91 | @discussion This function returns a safe default digest algorithm for a particular algorithm, and is used automatically by the Keychain framework when necessary. This is used when performing public-key cryptographic operations, to determine for example an appropriate digest for RSA/DSA/FEE/etc. 92 | 93 | At time of writing there is no way to override these defaults, neither here nor on a per-operation basis. If you require such functionality, submit a feature request to the author or on Sourceforge (http://www.sourceforge.net/projects/keychain/) to voice your interest. 94 | @param algorithm The algorithm. Note that not all algorithms are known or supported, in which case CSSM_ALGID_NONE is returned. 95 | @result Returns a [hopefully] appropriate default digest algorithm for the given algorithm, or CSSM_ALGID_NONE if the algorithm is not explicitly supported. */ 96 | 97 | CSSM_ALGORITHMS defaultDigestForAlgorithm(CSSM_ALGORITHMS algorithm); 98 | --------------------------------------------------------------------------------