Skip to content

Commit 6848b58

Browse files
author
Danny Greg
committed
Merge branch 'develop'
2 parents 989ddf4 + e019fe5 commit 6848b58

10 files changed

+370
-186
lines changed

objc/CFobError.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// CFobError.h
3+
// cocoafob
4+
//
5+
// Created by Danny Greg on 24/08/2010.
6+
// Copyright 2010 Realmac Software. All rights reserved.
7+
// Licensed under CC Attribution Licence 3.0 <http://creativecommons.org/licenses/by/3.0/>
8+
//
9+
10+
#import <Foundation/Foundation.h>
11+
12+
enum _CFobErrorCode {
13+
CFobErrorCodeInvalidKey = -1,
14+
CFobErrorCodeCouldNotDecode = -2,
15+
CFobErrorCodeSigningFailed = -3,
16+
CFobErrorCodeCouldNotEncode = -4,
17+
CFobErrorCodeNoName = -5,
18+
};
19+
20+
void CFobAssignErrorWithDescriptionAndCode(NSError **err, NSString *description, NSInteger code);

objc/CFobError.m

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// CFobError.h
3+
// cocoafob
4+
//
5+
// Created by Danny Greg on 24/08/2010.
6+
// Copyright 2010 Realmac Software. All rights reserved.
7+
// Licensed under CC Attribution Licence 3.0 <http://creativecommons.org/licenses/by/3.0/>
8+
//
9+
10+
#import "CFobError.h"
11+
12+
#import "CFobLicVerifier.h"
13+
14+
void CFobAssignErrorWithDescriptionAndCode(NSError **err, NSString *description, NSInteger code)
15+
{
16+
if (err != NULL)
17+
*err = [NSError errorWithDomain:[[NSBundle bundleForClass:[CFobLicVerifier class]] bundleIdentifier] code:code userInfo:[NSDictionary dictionaryWithObject:NSLocalizedStringFromTableInBundle(description, nil, [NSBundle bundleForClass:[CFobLicVerifier class]], nil) forKey:NSLocalizedDescriptionKey]];
18+
}

objc/CFobLicGenerator.h

+5-29
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,25 @@
1818
@discussion Given user name and DSA private key, generates a human-readable registration code.
1919
*/
2020
@interface CFobLicGenerator : NSObject {
21-
DSA *dsa;
22-
NSString *regName;
23-
NSString *regCode;
24-
NSString *lastError;
21+
DSA *_dsa;
2522
}
2623

27-
@property (nonatomic, copy) NSString *regName;
28-
@property (nonatomic, copy) NSString *regCode;
29-
@property (nonatomic, copy) NSString *lastError;
30-
31-
/*!
32-
@method generatorWithPrivateKey:
33-
@abstract Creates a new registration code generator given DSA private key.
34-
@discussion Use this class method to create an autoreleased registration code generator.
35-
@param privKey PEM-encoded non-encrypted DSA private key.
36-
@result A new autoreleased registration code generator object.
37-
*/
38-
+ (id)generatorWithPrivateKey:(NSString *)privKey;
39-
40-
/*!
41-
@method initWithPrivateKey:
42-
@abstract Designated initializer that takes a DSA private key.
43-
@discussion Initializes registration code generator using a DSA private key.
44-
@param privKey PEM-encoded non-encrypted DSA private key.
45-
@result An initialized registration code generator object.
46-
*/
47-
- (id)initWithPrivateKey:(NSString *)privKey;
48-
4924
/*!
5025
@method setPrivateKey:
5126
@abstract Sets a new DSA private key.
5227
@discussion Sets a new DSA private key to be used for subsequent generated registration codes.
5328
@param privKey PEM-encoded non-encrypted DSA private key.
5429
@result YES on success, NO on error.
5530
*/
56-
- (BOOL)setPrivateKey:(NSString *)privKey;
31+
- (BOOL)setPrivateKey:(NSString *)privKey error:(NSError **)err;
5732

5833
/*!
5934
@method generate
6035
@abstract Generates a registration code from regName property.
6136
@discussion Takes regName property and DSA private key and generates a new registration code that is placed in regCode property.
62-
@result YES on success, NO on error.
37+
@param The name or registration string to generate a serial number for.
38+
@result The serial number as a string, nil on failure.
6339
*/
64-
- (BOOL)generate;
40+
- (NSString *)generateRegCodeForName:(NSString *)name error:(NSError **)err;
6541

6642
@end

objc/CFobLicGenerator.m

+62-47
Original file line numberDiff line numberDiff line change
@@ -8,136 +8,151 @@
88
// Licensed under CC Attribution Licence 3.0 <http://creativecommons.org/licenses/by/3.0/>
99
//
1010

11+
#import "CFobLicGenerator.h"
12+
13+
#import "CFobError.h"
14+
1115
#import "NSData+PECrypt.h"
1216
#import "NSString+PECrypt.h"
13-
#import "CFobLicGenerator.h"
17+
1418
#import <openssl/evp.h>
1519
#import <openssl/err.h>
1620
#import <openssl/pem.h>
1721

22+
//***************************************************************************
1823

1924
@interface CFobLicGenerator ()
25+
26+
@property (nonatomic, assign) DSA *dsa;
27+
2028
- (void)initOpenSSL;
2129
- (void)shutdownOpenSSL;
30+
2231
@end
2332

2433

2534
@implementation CFobLicGenerator
2635

27-
@synthesize regName;
28-
@synthesize regCode;
29-
@synthesize lastError;
30-
31-
#pragma mark -
32-
#pragma mark Class methods
33-
34-
+ (id)generatorWithPrivateKey:(NSString *)privKey {
35-
return [[[CFobLicGenerator alloc] initWithPrivateKey:privKey] autorelease];
36-
}
36+
@synthesize dsa = _dsa;
3737

3838
#pragma mark -
3939
#pragma mark Lifecycle
4040

41-
- (id)init {
42-
return [self initWithPrivateKey:nil];
43-
}
44-
45-
- (id)initWithPrivateKey:(NSString *)privKey {
46-
if (![super init])
41+
- (id)init
42+
{
43+
if ([super init] == nil)
4744
return nil;
45+
4846
[self initOpenSSL];
49-
[self setPrivateKey:privKey];
47+
5048
return self;
5149
}
5250

5351
- (void)finalize
5452
{
55-
if (dsa)
56-
DSA_free(dsa);
53+
if (self.dsa)
54+
DSA_free(self.dsa);
55+
5756
[self shutdownOpenSSL];
5857
[super finalize];
5958
}
6059

61-
- (void)dealloc {
62-
if (dsa)
63-
DSA_free(dsa);
64-
self.regCode = nil;
65-
self.regName = nil;
66-
self.lastError = nil;
60+
- (void)dealloc
61+
{
62+
if (self.dsa)
63+
DSA_free(self.dsa);
64+
6765
[self shutdownOpenSSL];
6866
[super dealloc];
6967
}
7068

7169
#pragma mark -
7270
#pragma mark API
7371

74-
- (BOOL)setPrivateKey:(NSString *)privKey {
72+
- (BOOL)setPrivateKey:(NSString *)privKey error:(NSError **)err
73+
{
7574
// Validate the argument.
76-
if (!privKey || ![privKey length]) {
77-
self.lastError = @"Invalid key";
75+
if (privKey == nil || [privKey length] < 1) {
76+
CFobAssignErrorWithDescriptionAndCode(err, @"Invalid private key.", CFobErrorCodeInvalidKey);
7877
return NO;
7978
}
80-
if (dsa)
81-
DSA_free(dsa);
82-
dsa = DSA_new();
79+
80+
if (self.dsa)
81+
DSA_free(self.dsa);
82+
self.dsa = DSA_new();
8383
// Prepare BIO to read PEM-encoded private key from memory.
8484
// Prepare buffer given NSString.
8585
const char *privkeyCString = [privKey UTF8String];
8686
BIO *bio = BIO_new_mem_buf((void *)privkeyCString, -1);
87-
PEM_read_bio_DSAPrivateKey(bio, &dsa, NULL, NULL);
87+
PEM_read_bio_DSAPrivateKey(bio, &_dsa, NULL, NULL);
8888
BOOL result = YES;
89-
if (!dsa->priv_key) {
90-
self.lastError = @"Unable to decode key";
89+
if (!self.dsa->priv_key) {
90+
CFobAssignErrorWithDescriptionAndCode(err, @"Unable to decode key.", CFobErrorCodeCouldNotDecode);
9191
result = NO;
9292
}
9393
// Cleanup BIO
9494
BIO_vfree(bio);
9595
return result;
9696
}
9797

98-
- (BOOL)generate {
99-
if (![regName length] || !dsa || !dsa->priv_key)
100-
return NO;
101-
NSData *digest = [regName sha1];
98+
- (NSString *)generateRegCodeForName:(NSString *)name error:(NSError **)err
99+
{
100+
if (name == nil || [name length] < 1) {
101+
CFobAssignErrorWithDescriptionAndCode(err, @"No name provided.", CFobErrorCodeNoName);
102+
return nil;
103+
}
104+
105+
if (!self.dsa || !self.dsa->priv_key) {
106+
CFobAssignErrorWithDescriptionAndCode(err, @"Invalid private key.", CFobErrorCodeInvalidKey);
107+
return nil;
108+
}
109+
110+
NSData *digest = [name sha1];
102111
unsigned int siglen;
103112
unsigned char sig[100];
104-
int check = DSA_sign(NID_sha1, [digest bytes], [digest length], sig, &siglen, dsa);
113+
int check = DSA_sign(NID_sha1, [digest bytes], [digest length], sig, &siglen, self.dsa);
105114
if (!check) {
106-
self.lastError = @"Signing failed";
115+
CFobAssignErrorWithDescriptionAndCode(err, @"Signing failed.", CFobErrorCodeSigningFailed);
107116
return NO;
108117
}
118+
109119
// Encode signature in Base32
110120
NSData *signature = [NSData dataWithBytes:sig length:siglen];
111121
NSString *b32Orig = [signature base32];
112122
if (!b32Orig || ![b32Orig length]) {
113-
self.lastError = @"Unable to encode in base32";
123+
CFobAssignErrorWithDescriptionAndCode(err, @"Unable to encode in base32", CFobErrorCodeCouldNotEncode);
114124
return NO;
115125
}
126+
116127
// Replace Os with 8s and Is with 9s
117128
NSString *replacedOWith8 = [b32Orig stringByReplacingOccurrencesOfString:@"O" withString:@"8"];
118129
NSString *b32 = [replacedOWith8 stringByReplacingOccurrencesOfString:@"I" withString:@"9"];
130+
119131
// Cut off the padding.
120-
NSString *regKeyNoPadding = [b32 stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]];
132+
NSString *regKeyNoPadding = [b32 stringByReplacingOccurrencesOfString:@"=" withString:@""];
133+
121134
// Add dashes every 5 characters.
122135
NSMutableString *serial = [NSMutableString stringWithString:regKeyNoPadding];
123136
NSUInteger index = 5;
124137
while (index < [serial length]) {
125138
[serial insertString:@"-" atIndex:index];
126139
index += 6;
127140
}
128-
self.regCode = serial;
129-
return YES;
141+
142+
return serial;
130143
}
131144

132145
#pragma mark -
133146
#pragma mark OpenSSL Lifecycle
134147

135-
- (void)initOpenSSL {
148+
- (void)initOpenSSL
149+
{
136150
OpenSSL_add_all_algorithms();
137151
ERR_load_crypto_strings();
138152
}
139153

140-
- (void)shutdownOpenSSL {
154+
- (void)shutdownOpenSSL
155+
{
141156
EVP_cleanup();
142157
ERR_free_strings();
143158
}

objc/CFobLicVerifier.h

+7-31
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,11 @@
1818
@discussion Verifies CocoaFob-style registration key given licensing information (for example, application name, user name, and number of copies as suggested in Potion Store) and signature in human-readable format. A signature is a base32-encoded bignum with padding removed and dashes inserted.
1919
*/
2020
@interface CFobLicVerifier : NSObject {
21-
DSA *dsa;
22-
NSString *regName;
23-
NSString *regCode;
24-
NSArray *blacklist;
25-
NSString *lastError;
21+
DSA *_dsa;
22+
NSArray *_blacklist;
2623
}
2724

28-
@property (nonatomic, copy) NSString *regName;
29-
@property (nonatomic, copy) NSString *regCode;
30-
@property (nonatomic, retain) NSArray *blacklist;
31-
@property (nonatomic, copy) NSString *lastError;
32-
33-
/*!
34-
@method verifierWithPublicKey:
35-
@abstract Creates a new registration code verifier object given a DSA public key.
36-
@discussion Creates a new registration code verifier object. Use setRegName: and setRegKey: on it, then call verify to verify registration key.
37-
@param pubKey A DSA public key in PEM encoding. See completePublicKeyPEM: for help on how to construct a PEM-encoded DSA public key.
38-
@result A new autoreleased registration code verifier object.
39-
*/
40-
+ (id)verifierWithPublicKey:(NSString *)pubKey;
25+
@property (nonatomic, copy) NSArray *blacklist;
4126

4227
/*!
4328
@method completePublicKeyPEM:
@@ -48,30 +33,21 @@
4833
*/
4934
+ (NSString *)completePublicKeyPEM:(NSString *)partialPEM;
5035

51-
/*!
52-
@method initWithPublicKey:
53-
@abstract Designated initialiser.
54-
@discussion Initialises a newly allocated registration code verifier object with a PEM-encoded DSA public key.
55-
@param pubKey A PEM-encoded DSA public key. See completePublicKeyPEM: for help on how to constuct a PEM-encoded DSA key string from base64-encoded lines.
56-
@result An initialised registration code verifier object.
57-
*/
58-
- (id)initWithPublicKey:(NSString *)pubKey;
59-
6036
/*!
6137
@method setPubKey:
6238
@abstract Sets DSA public key to the passed key in PEM format.
6339
@discussion Sets DSA public key in the verifier object to the argument which is a PEM-encoded DSA public key.
6440
@param pubKey PEM-encoded DSA public key.
65-
@result YES on success, NO on error (check lastError property).
41+
@result YES on success, NO on error (err may or may not be populated).
6642
*/
67-
- (BOOL)setPublicKey:(NSString *)pubKey;
43+
- (BOOL)setPublicKey:(NSString *)pubKey error:(NSError **)err;
6844

6945
/*!
7046
@method verify
7147
@abstract Verifies registration code in the regName property using public DSA key.
7248
@discussion Takes regName and regCode properties and verifies regCode against regName using public DSA certificate.
73-
@result YES if regCode is valid, NO if not.
49+
@result YES if regCode is valid, NO if not. If an error was recovered it will be set in the err paramater
7450
*/
75-
- (BOOL)verify;
51+
- (BOOL)verifyRegCode:(NSString *)regCode forName:(NSString *)name error:(NSError **)err;
7652

7753
@end

0 commit comments

Comments
 (0)