Skip to content

Commit ad35694

Browse files
committed
Merge pull request #31 from TongG/test-for-wiki
Completed the Comparison Between Keychain Services and WaxSealCore section of README.md
2 parents 54fd67a + bd5bea0 commit ad35694

File tree

2 files changed

+225
-10
lines changed

2 files changed

+225
-10
lines changed

README.md

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,83 @@ WSCKeychain* emptyKeychain = [ [ WSCKeychainManager defaultManager ]
6868
// emptyKeychain will be released automatically.
6969
```
7070

71-
**Find the following Internet passphrase:**
71+
**Find the following Internet passphrase then print its Account Name, Passphrase and Comment**
7272

7373
<img src="http://i.imgbox.com/eeiU5Ymr.png" title="IMDb Passphrase" border="0" height="498" width="501" />
7474

75-
* using pure C API of *Keychain Services*:
75+
* using pure C API of *Keychain Services* (OMG! Give me a break!😲🔫):
7676

7777
```objective-c
78-
OMG! Give me a break!
78+
OSStatus resultCode = errSecSuccess;
79+
80+
// Attributes that will be used for constructing search criteria
81+
char* label = "secure.imdb.com";
82+
SecProtocolType* ptrProtocolType = malloc( sizeof( SecProtocolType ) );
83+
*ptrProtocolType = kSecProtocolTypeHTTPS;
84+
85+
SecKeychainAttribute attrs[] = { { kSecLabelItemAttr, ( UInt32 )strlen( label ), ( void* )label }
86+
, { kSecProtocolItemAttr, ( UInt32 )sizeof( SecProtocolType ), ( void* )ptrProtocolType }
87+
};
88+
89+
SecKeychainAttributeList attrsList = { sizeof( attrs ) / sizeof( attrs[ 0 ] ), attrs };
90+
91+
// Creates a search object matching the given list of search criteria.
92+
SecKeychainSearchRef searchObject = NULL;
93+
if ( ( resultCode = SecKeychainSearchCreateFromAttributes( NULL
94+
, kSecInternetPasswordItemClass
95+
, &attrsList
96+
, &searchObject
97+
) ) == errSecSuccess )
98+
{
99+
SecKeychainItemRef matchedItem = NULL;
100+
101+
// Finds the next keychain item matching the given search criteria.
102+
while ( ( resultCode = SecKeychainSearchCopyNext( searchObject, &matchedItem ) ) != errSecItemNotFound )
103+
{
104+
SecKeychainAttribute theAttributes[] = { { kSecAccountItemAttr, 0, NULL }
105+
, { kSecCommentItemAttr, 0, NULL }
106+
};
107+
108+
SecKeychainAttributeList theAttrList = { sizeof( theAttributes ) / sizeof( theAttributes[ 0 ] ), theAttributes };
109+
UInt32 lengthOfPassphrase = 0;
110+
char* passphraseBuffer = NULL;
111+
if ( ( resultCode = SecKeychainItemCopyContent( matchedItem
112+
, NULL
113+
, &theAttrList
114+
, &lengthOfPassphrase
115+
, ( void** )&passphraseBuffer
116+
) ) == errSecSuccess )
117+
{
118+
NSLog( @"\n==============================\n" );
119+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithBytes: passphraseBuffer length: lengthOfPassphrase encoding: NSUTF8StringEncoding ] autorelease ] );
120+
121+
for ( int _Index = 0; _Index < theAttrList.count; _Index++ )
122+
{
123+
SecKeychainAttribute attrStruct = theAttrList.attr[ _Index ];
124+
NSString* attributeValue = [ [ [ NSString alloc ] initWithBytes: attrStruct.data length: attrStruct.length encoding: NSUTF8StringEncoding ] autorelease ];
125+
126+
if ( attrStruct.tag == kSecAccountItemAttr )
127+
NSLog( @"IMDb User Name: %@", attributeValue );
128+
else if ( attrStruct.tag == kSecCommentItemAttr )
129+
NSLog( @"Comment: %@", attributeValue );
130+
}
131+
132+
NSLog( @"\n==============================\n" );
133+
}
134+
135+
SecKeychainItemFreeContent( &theAttrList, passphraseBuffer );
136+
CFRelease( matchedItem );
137+
}
138+
}
139+
140+
if ( ptrProtocolType )
141+
free( ptrProtocolType );
142+
143+
if ( searchObject )
144+
CFRelease( searchObject );
79145
```
80146
81-
* using *WaxSealCore*:
147+
* using *WaxSealCore* (Just a few lines of Objective-C code):
82148
83149
```objective-c
84150
NSError* error = nil;
@@ -91,20 +157,36 @@ WSCPassphraseItem* IMDbLoginPassphrase = ( WSCPassphraseItem* )[ [ WSCKeychain l
91157
itemClass: WSCKeychainItemClassInternetPassphraseItem
92158
error: &error ];
93159
94-
// WaxSealCore supports **Unicode-based** search, so you can use Emoji or Chinese in your search criteria.
160+
// WaxSealCore supports Unicode-based search, so you can use Emoji or Chinese in your search criteria.
95161
// One step. So easy, is not it?
96-
162+
```
163+
164+
Print its Account Name, Passphrase and Comment:
165+
166+
```objective-c
97167
if ( IMDbLoginPassphrase )
98168
{
99-
NSLog( @"Huh, found it!" );
169+
NSLog( @"==============================" );
170+
// Use the `account` property
100171
NSLog( @"IMDb User Name: %@", IMDbLoginPassphrase.account );
172+
173+
// Use the `passphrase` property
174+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithData: IMDbLoginPassphrase.passphrase encoding: NSUTF8StringEncoding ] autorelease ] );
175+
176+
// Use the `comment` property
101177
NSLog( @"Comment: %@", IMDbLoginPassphrase.comment );
178+
NSLog( @"==============================" );
102179

180+
// -setComment:
103181
IMDbLoginPassphrase.comment = @"👿👿👿👿👿👿";
104182
}
105183
else
106184
NSLog( @"I'm so sorry!" );
185+
```
186+
187+
Batch Search:
107188
189+
```objective-c
108190
// Find all the Internet passphrases that met the given search criteria
109191
NSArray* passphrases = [ [ WSCKeychain login ]
110192
// Batch search
@@ -118,9 +200,11 @@ if ( passphrases.count != 0 )
118200
{
119201
for ( WSCPassphraseItem* _Passphrase in passphrases )
120202
{
121-
NSLog( @"Huh, got one!" );
122-
NSLog( @"IMDb User Name: %@", _Passphrase.account );
123-
NSLog( @"Comment: %@", _Passphrase.comment );
203+
NSLog( @"==============================" );
204+
NSLog( @"IMDb User Name: %@", IMDbLoginPassphrase.account );
205+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithData: IMDbLoginPassphrase.passphrase encoding: NSUTF8StringEncoding ] autorelease ] );
206+
NSLog( @"Comment: %@", IMDbLoginPassphrase.comment );
207+
NSLog( @"==============================" );
124208
125209
_Passphrase.comment = @"👺👹👺👹";
126210
}

WaxSealCoreTests/WSCKeychainTests.m

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,137 @@ - ( void ) tearDown
6363
// TODO: Put teardown code here. This method is called after the invocation of each test method in the class.
6464
}
6565

66+
- ( void ) testForWiki_findKeychainItemInCocoa
67+
{
68+
NSError* error = nil;
69+
70+
WSCPassphraseItem* IMDbLoginPassphrase = ( WSCPassphraseItem* )[ [ WSCKeychain login ]
71+
findFirstKeychainItemSatisfyingSearchCriteria: @{ WSCKeychainItemAttributeLabel : @"secure.imdb.com"
72+
, WSCKeychainItemAttributeProtocol : WSCInternetProtocolCocoaValue( WSCInternetProtocolTypeHTTPS )
73+
, WSCKeychainItemAttributeComment : @"👺👹👺👹"
74+
}
75+
itemClass: WSCKeychainItemClassInternetPassphraseItem
76+
error: &error ];
77+
78+
// WaxSealCore supports Unicode-based search, so you can use Emoji or Chinese in your search criteria.
79+
// One step. So easy, is not it?
80+
81+
if ( IMDbLoginPassphrase )
82+
{
83+
NSLog( @"==============================" );
84+
// Use the `account` property
85+
NSLog( @"IMDb User Name: %@", IMDbLoginPassphrase.account );
86+
87+
// Use the `passphrase` property
88+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithData: IMDbLoginPassphrase.passphrase encoding: NSUTF8StringEncoding ] autorelease ] );
89+
90+
// Use the `comment` property
91+
NSLog( @"Comment: %@", IMDbLoginPassphrase.comment );
92+
NSLog( @"==============================" );
93+
94+
// -setComment:
95+
IMDbLoginPassphrase.comment = @"👿👿👿👿👿👿";
96+
}
97+
else
98+
NSLog( @"I'm so sorry!" );
99+
100+
// Find all the Internet passphrases that met the given search criteria
101+
NSArray* passphrases = [ [ WSCKeychain login ]
102+
// Batch search
103+
findAllKeychainItemsSatisfyingSearchCriteria: @{ WSCKeychainItemAttributeLabel : @"secure.imdb.com"
104+
, WSCKeychainItemAttributeProtocol : WSCInternetProtocolCocoaValue( WSCInternetProtocolTypeHTTPS )
105+
, WSCKeychainItemAttributeComment : @"👿👿👿👿👿👿"
106+
}
107+
itemClass: WSCKeychainItemClassInternetPassphraseItem
108+
error: &error ];
109+
if ( passphrases.count != 0 )
110+
{
111+
for ( WSCPassphraseItem* _Passphrase in passphrases )
112+
{
113+
NSLog( @"==============================" );
114+
NSLog( @"IMDb User Name: %@", IMDbLoginPassphrase.account );
115+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithData: IMDbLoginPassphrase.passphrase encoding: NSUTF8StringEncoding ] autorelease ] );
116+
NSLog( @"Comment: %@", IMDbLoginPassphrase.comment );
117+
NSLog( @"==============================" );
118+
119+
_Passphrase.comment = @"👺👹👺👹";
120+
}
121+
}
122+
else
123+
NSLog( @"I'm so sorry!" );
124+
}
125+
126+
- ( void ) testForWiki_findKeychainItemInC
127+
{
128+
OSStatus resultCode = errSecSuccess;
129+
130+
// Attributes that will be used for constructing search criteria
131+
char* label = "secure.imdb.com";
132+
SecProtocolType* ptrProtocolType = malloc( sizeof( SecProtocolType ) );
133+
*ptrProtocolType = kSecProtocolTypeHTTPS;
134+
135+
SecKeychainAttribute attrs[] = { { kSecLabelItemAttr, ( UInt32 )strlen( label ), ( void* )label }
136+
, { kSecProtocolItemAttr, ( UInt32 )sizeof( SecProtocolType ), ( void* )ptrProtocolType }
137+
};
138+
139+
SecKeychainAttributeList attrsList = { sizeof( attrs ) / sizeof( attrs[ 0 ] ), attrs };
140+
141+
// Creates a search object matching the given list of search criteria.
142+
SecKeychainSearchRef searchObject = NULL;
143+
if ( ( resultCode = SecKeychainSearchCreateFromAttributes( NULL
144+
, kSecInternetPasswordItemClass
145+
, &attrsList
146+
, &searchObject
147+
) ) == errSecSuccess )
148+
{
149+
SecKeychainItemRef matchedItem = NULL;
150+
151+
// Finds the next keychain item matching the given search criteria.
152+
while ( ( resultCode = SecKeychainSearchCopyNext( searchObject, &matchedItem ) ) != errSecItemNotFound )
153+
{
154+
SecKeychainAttribute theAttributes[] = { { kSecAccountItemAttr, 0, NULL }
155+
, { kSecCommentItemAttr, 0, NULL }
156+
};
157+
158+
SecKeychainAttributeList theAttrList = { sizeof( theAttributes ) / sizeof( theAttributes[ 0 ] ), theAttributes };
159+
UInt32 lengthOfPassphrase = 0;
160+
char* passphraseBuffer = NULL;
161+
if ( ( resultCode = SecKeychainItemCopyContent( matchedItem
162+
, NULL
163+
, &theAttrList
164+
, &lengthOfPassphrase
165+
, ( void** )&passphraseBuffer
166+
) ) == errSecSuccess )
167+
{
168+
NSLog( @"==============================" );
169+
170+
for ( int _Index = 0; _Index < theAttrList.count; _Index++ )
171+
{
172+
SecKeychainAttribute attrStruct = theAttrList.attr[ _Index ];
173+
NSString* attributeValue = [ [ [ NSString alloc ] initWithBytes: attrStruct.data length: attrStruct.length encoding: NSUTF8StringEncoding ] autorelease ];
174+
175+
if ( attrStruct.tag == kSecAccountItemAttr )
176+
NSLog( @"IMDb User Name: %@", attributeValue );
177+
else if ( attrStruct.tag == kSecCommentItemAttr )
178+
NSLog( @"Comment: %@", attributeValue );
179+
}
180+
181+
NSLog( @"Passphrase: %@", [ [ [ NSString alloc ] initWithBytes: passphraseBuffer length: lengthOfPassphrase encoding: NSUTF8StringEncoding ] autorelease ] );
182+
NSLog( @"==============================" );
183+
}
184+
185+
SecKeychainItemFreeContent( &theAttrList, passphraseBuffer );
186+
CFRelease( matchedItem );
187+
}
188+
}
189+
190+
if ( ptrProtocolType )
191+
free( ptrProtocolType );
192+
193+
if ( searchObject )
194+
CFRelease( searchObject );
195+
}
196+
66197
- ( void ) testDeletingKeychainItem
67198
{
68199
NSError* error = nil;

0 commit comments

Comments
 (0)