// // DemoController.m // DemoUtility // // Created by Andrew Salamon on 9/12/08. // Copyright 2008 Machine Perception Laboratory, University of California San Diego.. All rights reserved. // #import "DemoController.h" #include #include #include @interface DemoController(PrivateMethods) - (void)testLicenseEncryption; @end @implementation DemoController + (void)initialize { [super initialize] ; [self setKeys:[NSArray arrayWithObjects: @"start", @"duration", nil] triggerChangeNotificationsForDependentKey:@"end"]; [self setKeys:[NSArray arrayWithObjects: @"end", nil] triggerChangeNotificationsForDependentKey:@"duration"]; [self setKeys:[NSArray arrayWithObjects: @"name", @"licenseType", nil] triggerChangeNotificationsForDependentKey:@"enableGenerateButton"]; } - (id)init { if( self = [super init] ) { util = new DemoUtil; license = NULL; verifier = NULL; NSString *pathToKey = [[NSBundle bundleForClass:[self class]] pathForResource:@"private" ofType:@"pem"]; license = new CERT::License(); license->setPrivateKeyPath( [pathToKey UTF8String] ); license->setType( CERT::License::licensed ); verifier = new CERT::LicenseVerifier( [pathToKey UTF8String] ); } return self; } - (void)dealloc { delete util; delete license; delete verifier; [super dealloc]; } - (void)awakeFromNib { } - (IBAction)generateLicenseFile:(id)sender { NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setCanChooseDirectories:NO]; [panel setAllowsMultipleSelection:NO]; [panel setCanChooseFiles:YES]; [panel setMessage:@"Choose the CERT application that is to be licensed."]; [panel beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"app", @"certlic", nil] modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(openSourcePanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; } - (void)openSourcePanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo { if( returnCode == NSOKButton ) { NSArray *filenames = [panel filenames]; if( [filenames count] > 0 ) { NSString *path = [filenames objectAtIndex:0]; if( [path length] > 0 ) { path = [path stringByAppendingPathComponent:@"Contents/Resources/License.certlic"]; std::ofstream ofstr( [path UTF8String] ); if( ofstr.good() ) { try { ofstr << *license; } catch( const CERT::Licensing::keyException &exc ) { [NSAlert alertWithMessageText:@"Missing Private Encryption Key." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Unable to write license file."]; } catch( const CERT::Licensing::encryptionException &exc ) { [NSAlert alertWithMessageText:@"Unable to encrypt license information." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Unable to write license file."]; } } else { [NSAlert alertWithMessageText:@"Unable to write license file." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Unable to write license file. Make sure you have permission to write to the chosen CERT application."]; } } } } } - (IBAction)readLicenseFile:(id)sender { NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setCanChooseDirectories:NO]; [panel setAllowsMultipleSelection:NO]; [panel setCanChooseFiles:YES]; [panel setMessage:@"Choose the CERT application whose license you want to display."]; [panel beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"app", @"certlic", nil] modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(readLicensePanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; } - (void)readLicensePanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo { if( returnCode == NSOKButton ) { NSArray *filenames = [panel filenames]; if( [filenames count] > 0 ) { NSString *path = [filenames objectAtIndex:0]; if( [path length] > 0 ) { path = [path stringByAppendingPathComponent:@"Contents/Resources/License.certlic"]; [self willChangeValueForKey:@"name"]; [self willChangeValueForKey:@"start"]; [self willChangeValueForKey:@"end"]; [self willChangeValueForKey:@"duration"]; [self willChangeValueForKey:@"licenseType"]; std::ifstream ifstr( [path UTF8String] ); if( ifstr.good() ) { ifstr >> *license; } else { [NSAlert alertWithMessageText:@"Unable to read license file." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Unable to read license file."]; } [self didChangeValueForKey:@"name"]; [self didChangeValueForKey:@"start"]; [self didChangeValueForKey:@"end"]; [self didChangeValueForKey:@"duration"]; [self didChangeValueForKey:@"licenseType"]; } } } } - (void)setLicenseType:(int)tag { int type = 0; switch( tag ) { case 0: type = CERT::License::internal; break; case 1: type = CERT::License::evaluation; break; case 2: type = CERT::License::licensed; break; case 3: type = CERT::License::invalid; break; } if( license->getType() != type ) { [self willChangeValueForKey:@"name"]; [self willChangeValueForKey:@"start"]; [self willChangeValueForKey:@"end"]; [self willChangeValueForKey:@"duration"]; license->setType( type ); [self didChangeValueForKey:@"name"]; [self didChangeValueForKey:@"start"]; [self didChangeValueForKey:@"end"]; [self didChangeValueForKey:@"duration"]; } } - (int)licenseType { int type = license->getType(); int tag = 0; if( CERT::License::internal == type ) tag = 0; else if( CERT::License::evaluation == type) tag = 1; else if( CERT::License::licensed == type) tag = 2; else if( CERT::License::invalid == type) tag = 3; return tag; } - (BOOL)licenseIsInternal { return (license->getType() == CERT::License::internal); } - (BOOL)licenseIsEvaluation { return (license->getType() == CERT::License::evaluation); } - (BOOL)licenseIsLicensed { return (license->getType() == CERT::License::licensed); } - (BOOL)licenseIsInvalid { return (license->getType() == CERT::License::invalid); } - (BOOL)enableNameField { return ([self licenseIsLicensed]); } - (BOOL)enableDateFields { return ([self licenseIsLicensed]); } - (BOOL)enableDurationField { return ([self licenseIsLicensed] || [self licenseIsEvaluation]); } - (BOOL)enableGenerateButton { if( [self licenseIsEvaluation] || ([[self name] length] > 0) ) return YES; return NO; } - (void)testLicenseEncryption { std::string licStr( license->toString() ); NSLog( @"License Text: %s", licStr.c_str() ); std::string cyphertext = verifier->encrypt( licStr ); NSLog( @"Cypher Text: %s", cyphertext.c_str() ); std::string plaintext = verifier->decrypt( cyphertext ); NSLog( @"Plain Text: %s", plaintext.c_str() ); } - (NSWindow *)window { return window; } - (NSCalendarDate *)date { return [[date retain] autorelease]; } - (void)setDate:(NSCalendarDate *)value { if (date != value) { [date release]; date = [value copy]; NSLog( @"Date value changed." ); int dt = [date timeIntervalSince1970]; // long odt = time(NULL); dt = util->pub_obfuscate(dt); // int pub_deobfuscate(int num); [obView setIntValue:dt]; } } - (NSString *)name { NSString *nm = [NSString stringWithCString:license->getName().c_str()]; if( 0 == [nm length] ) return nil; return nm; } - (void)setName:(NSString *)value { if( !value ) value = @""; if( [value length] > 90 ) value = [value substringToIndex:90]; license->setName( [value UTF8String] ); } - (NSDate *)start { NSDate *res = NULL; bg::date dt = license->getStartDate(); if( dt.is_not_a_date() ) { // res = [NSDate distantPast]; } else { tm _tm = to_tm( dt ); res = [NSDate dateWithTimeIntervalSince1970:mktime(&_tm)]; } return res; } - (void)setStart:(NSDate *)value { time_t stime = [value timeIntervalSince1970]; license->setStartDate( bg::date_from_tm( *localtime( &stime ) ) ); } - (NSDate *)end { NSDate *res = NULL; bg::date dt = license->getEndDate(); if( dt.is_not_a_date() ) { // res = [NSDate distantFuture]; } else { tm _tm = to_tm( dt ); res = [NSDate dateWithTimeIntervalSince1970:mktime(&_tm)]; } return res; } - (void)setEnd:(NSDate *)value { time_t stime = [value timeIntervalSince1970]; license->setEndDate( bg::date_from_tm( *localtime( &stime ) ) ); } - (NSDate *)minimumEnd { return [NSDate dateWithTimeIntervalSince1970:([[self start] timeIntervalSince1970] + 60*60*24)]; } - (unsigned int)duration { return license->getDuration(); } - (void)setDuration:(unsigned int)value { license->setDuration( value ); } @end