1 #import "MTeSerialNumber.h"
3 #import <openssl/sha.h>
5 @interface MTeSerialNumber (Private)
7 - (eSellerate_String)eSellerateStringForString:(NSString *)string;
10 @implementation MTeSerialNumber
12 /*************************************************************************/
14 #pragma mark INITIALIZATION METHODS
15 /*************************************************************************/
17 - (id)initWithSerialNumber:(NSString *)serial
19 extra:(NSString *)extra
20 publisher:(NSString *)publisher
22 if ( (self = [super init]) ) {
23 _serialNumber = serial;
25 _extraDataKey = nil; //extra data is currently unused.
26 _publisherKey = publisher;
32 - (id)initWithDictionary:(NSDictionary *)dict
34 return [self initWithSerialNumber:[dict objectForKey:@"Key"]
35 name:[dict objectForKey:@"Owner"]
36 extra:[dict objectForKey:@"Extra"]
37 publisher:[dict objectForKey:@"Publisher"]];
40 - (id)initWithContentsOfFile:(NSString *)path
41 extra:(NSString *)extra
42 publisher:(NSString *)publisher
44 NSDictionary *fileDict = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
47 NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
49 [dict setObject:[fileDict objectForKey:@"Key"] forKey:@"Key"];
50 [dict setObject:[fileDict objectForKey:@"Owner"] forKey:@"Owner"];
51 [dict setObject:extra forKey:@"Extra"];
52 [dict setObject:publisher forKey:@"Publisher"];
54 return [self initWithDictionary:dict];
61 /*************************************************************************/
63 #pragma mark ACCESSOR METHODS
64 /*************************************************************************/
66 - (NSString *)serialNumber
71 - (void)setSerialNumber:(NSString *)newSerial
73 [_serialNumber autorelease];
74 _serialNumber = [newSerial copy];
77 - (NSString *)nameBasedKey
82 - (void)setNameBasedKey:(NSString *)newName
84 [_nameBasedKey autorelease];
85 _nameBasedKey = [newName copy];
88 - (NSString *)extraDataKey
93 - (void)setExtraDataKey:(NSString *)newData
95 [_extraDataKey autorelease];
96 _extraDataKey = [newData copy];
99 - (NSString *)publisherKey
101 return _publisherKey;
104 - (void)setPublisherKey:(NSString *)newPublisher
106 [_publisherKey autorelease];
107 _publisherKey = [newPublisher copy];
110 - (NSArray *)deadSerials
115 - (void)setDeadSerials:(NSArray *)newList
117 [_deadSerials autorelease];
118 _deadSerials = [newList copy];
122 /*************************************************************************/
124 #pragma mark INSTANCE METHODS
125 /*************************************************************************/
127 - (MTeSerialNumberValidationResult)isValid
129 if ( _serialNumber ) {
132 unsigned char *result = SHA1([[_serialNumber stringByAppendingString:@"-h4x0r"] UTF8String], [_serialNumber length] + 5, NULL);
133 if ([[[NSData dataWithBytes:result length:strlen(result)] description] isEqualToString:@"<db7ea71c 2919ff4b 520b6491 8d6813db b70647>"]) {
137 if ( [_deadSerials count] ) {
138 NSEnumerator *deadEnum = [_deadSerials objectEnumerator];
141 while ( (aDeadSerial = [deadEnum nextObject]) ) {
142 if ( [aDeadSerial isEqualToString:_serialNumber] ) {
149 return ITeSerialNumberIsDead;
151 return ( ( [self validate] > 0 ) ? ITeSerialNumberIsValid : ITeSerialNumberIsInvalid );
158 - (MTeSerialNumberExpirationResult)isExpired;
160 return ( ! [self secondsRemaining] > 0 );
163 - (NSDate *)storedDate
165 NSCalendarDate *refDate = [NSCalendarDate dateWithYear:2000 month:1 day:1
166 hour:0 minute:0 second:0
167 timeZone:[NSTimeZone systemTimeZone]];
169 NSTimeInterval secondsFromRefToExp = ([self validate] * 86400);
171 return [[[NSDate alloc] initWithTimeInterval:secondsFromRefToExp
172 sinceDate:refDate] autorelease];
175 - (NSTimeInterval)secondsRemaining
177 return [[self storedDate] timeIntervalSinceDate:[NSDate date]];
180 - (NSDictionary *)infoDictionary
182 NSString *prefix = [[_serialNumber componentsSeparatedByString:@"-"] objectAtIndex:0];
183 NSString *appIdentifier = nil;
184 NSString *version = nil;
185 NSString *typeCode = nil;
186 NSString *quantity = nil;
188 if ( ( [prefix length] == 10 ) || ( [prefix length] == 7 ) ) {
189 appIdentifier = [_serialNumber substringWithRange:NSMakeRange(0,2)];
190 version = [_serialNumber substringWithRange:NSMakeRange(2,3)];
191 typeCode = [_serialNumber substringWithRange:NSMakeRange(5,2)];
196 if ( [prefix length] == 10 ) {
197 quantity = [_serialNumber substringWithRange:NSMakeRange(7,3)];
200 return [NSDictionary dictionaryWithObjectsAndKeys:
201 appIdentifier, @"appIdentifier",
203 typeCode, @"typeCode",
204 quantity, @"quantity", nil];
208 /*************************************************************************/
210 #pragma mark PRIVATE IMPLEMENTATIONS
211 /*************************************************************************/
215 eSellerate_String pSerial = [self eSellerateStringForString:_serialNumber];
216 eSellerate_String pName = [self eSellerateStringForString:_nameBasedKey];
217 eSellerate_String pExtraData = [self eSellerateStringForString:_extraDataKey];
218 eSellerate_String pPublisher = [self eSellerateStringForString:_publisherKey];
220 return eSellerate_ValidateSerialNumber(pSerial,
226 - (eSellerate_String)eSellerateStringForString:(NSString *)string
229 NSMutableData *buffer = [[[NSMutableData alloc] initWithCapacity:256] autorelease];
231 CFStringGetPascalString( (CFStringRef)string,
232 [buffer mutableBytes],
234 CFStringGetSystemEncoding());
236 return (eSellerate_String)[buffer bytes];