├── .gitignore ├── EllipticLicense.h ├── EllipticLicenseDeveloper ├── AppController.h ├── AppController.m ├── EllipticLicenseDeveloper.xcodeproj │ ├── TemplateIcon.icns │ └── project.pbxproj ├── EllipticLicenseDeveloper_Prefix.pch ├── English.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ ├── MainMenu.xib │ └── MyDocument.xib ├── Info.plist ├── InvalidKey.png ├── MyDocument.h ├── MyDocument.m ├── ProductStore.h ├── ProductStore.m ├── ValidKey.png └── main.m ├── Framework ├── EllipticLicense.h ├── EllipticLicense.m ├── EllipticLicense.xcodeproj │ ├── TemplateIcon.icns │ └── project.pbxproj ├── EllipticLicense_Prefix.pch ├── English.lproj │ └── InfoPlist.strings ├── Info.plist ├── NSData+ELAdditions.h └── NSData+ELAdditions.m ├── LICENSE ├── README.markdown ├── Server ├── PHP │ ├── ELConfig.php │ └── ELGenerator.php └── elgen │ ├── Makefile │ ├── elgen.1 │ ├── elgen.xcodeproj │ └── project.pbxproj │ └── main.c ├── Static Library ├── EllipticLicense.xcodeproj │ ├── TemplateIcon.icns │ └── project.pbxproj ├── EllipticLicense_Prefix.pch └── README └── Test ├── Test.1 ├── Test.m ├── Test.xcodeproj ├── TemplateIcon.icns ├── dmitry.mode1v3 ├── dmitry.pbxuser └── project.pbxproj └── Test_Prefix.pch /.gitignore: -------------------------------------------------------------------------------- 1 | Builds/* 2 | _FOSSIL_ 3 | manifest 4 | manifest.uuid 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | *.xcworkspace 14 | !default.xcworkspace 15 | xcuserdata 16 | profile 17 | *.moved-aside 18 | 19 | -------------------------------------------------------------------------------- /EllipticLicense.h: -------------------------------------------------------------------------------- 1 | /* Interface for EllipticLicense framework or static library */ 2 | 3 | extern NSString *ELCurveNameSecp112r1; 4 | extern NSString *ELCurveNameSecp128r1; 5 | extern NSString *ELCurveNameSecp160r1; 6 | 7 | @interface EllipticLicense : NSObject 8 | 9 | - (id)initWithPublicKey:(NSString *)publicKey; 10 | - (id)initWithPublicKey:(NSString *)publicKey curveName:(NSString *)curve; 11 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 12 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey curveName:(NSString *)curve; 13 | - (void)setCurveName:(NSString *)name; 14 | - (void)setNumberOfDashGroupCharacters:(unsigned int)number; 15 | - (unsigned int)numberOfDashGroupCharacters; 16 | 17 | - (BOOL)setPublicKey:(NSString *)publicKey; 18 | - (BOOL)setPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 19 | - (NSString *)privateKey; 20 | - (NSString *)publicKey; 21 | 22 | - (void)setBlockedLicenseKeyHashes:(NSArray *)hashes; 23 | - (NSArray *)blockedLicenseKeyHashes; 24 | - (BOOL)isBlockedLicenseKey:(NSString *)licenseKey; 25 | 26 | - (BOOL)generateKeys; 27 | - (void)logKeys; 28 | 29 | - (NSString *)hashStringOfLicenseKey:(NSString *)licenseKey; 30 | 31 | - (NSString *)licenseKeyForName:(NSString *)name; 32 | - (BOOL)verifyLicenseKey:(NSString *)signature forName:(NSString *)name; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/AppController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppController.h 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 31.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import 22 | 23 | 24 | @interface AppController : NSObject 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/AppController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppController.m 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 31.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import "AppController.h" 22 | 23 | 24 | @implementation AppController 25 | 26 | - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender; 27 | { 28 | id documentController = [NSDocumentController sharedDocumentController]; 29 | 30 | // Reopen last document 31 | if ([[documentController recentDocumentURLs] count] > 0) { 32 | for (NSURL *url in [documentController recentDocumentURLs]) { 33 | if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]]) { 34 | if ([documentController openDocumentWithContentsOfURL:url display:YES error:nil]) 35 | return NO; 36 | } 37 | } 38 | } 39 | return YES; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/EllipticLicenseDeveloper.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/EllipticLicenseDeveloper/EllipticLicenseDeveloper.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/EllipticLicenseDeveloper.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A76B9DB106FE1780048097B /* libcrypto.0.9.8.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A76B9DA106FE1780048097B /* libcrypto.0.9.8.dylib */; }; 11 | 0A855F100F81243600AEAB7A /* ProductStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A855F0F0F81243600AEAB7A /* ProductStore.m */; }; 12 | 0A8563150F8181CC00AEAB7A /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8563140F8181CC00AEAB7A /* AppController.m */; }; 13 | 0A8563C40F8191BB00AEAB7A /* ValidKey.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A8563C30F8191BB00AEAB7A /* ValidKey.png */; }; 14 | 0A8563C90F81922E00AEAB7A /* InvalidKey.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A8563C80F81922E00AEAB7A /* InvalidKey.png */; }; 15 | 0A85648E0F82C4DF00AEAB7A /* libEllipticLicense.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A85648D0F82C4DF00AEAB7A /* libEllipticLicense.a */; }; 16 | 1DDD582C0DA1D0D100B32029 /* MyDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58280DA1D0D100B32029 /* MyDocument.xib */; }; 17 | 1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */; }; 18 | 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */; }; 19 | 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; }; 20 | 8D15AC310486D014006FF6A4 /* MyDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */; settings = {ATTRIBUTES = (); }; }; 21 | 8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 22 | 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 089C1660FE840EACC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 27 | 0A76B9DA106FE1780048097B /* libcrypto.0.9.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.0.9.8.dylib; path = /usr/lib/libcrypto.0.9.8.dylib; sourceTree = ""; }; 28 | 0A855DEC0F81050800AEAB7A /* EllipticLicense.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EllipticLicense.h; path = ../EllipticLicense.h; sourceTree = SOURCE_ROOT; }; 29 | 0A855F0E0F81243600AEAB7A /* ProductStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductStore.h; sourceTree = ""; }; 30 | 0A855F0F0F81243600AEAB7A /* ProductStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductStore.m; sourceTree = ""; }; 31 | 0A8563130F8181CC00AEAB7A /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = ""; }; 32 | 0A8563140F8181CC00AEAB7A /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = ""; }; 33 | 0A8563C30F8191BB00AEAB7A /* ValidKey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ValidKey.png; sourceTree = ""; }; 34 | 0A8563C80F81922E00AEAB7A /* InvalidKey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = InvalidKey.png; sourceTree = ""; }; 35 | 0A85648D0F82C4DF00AEAB7A /* libEllipticLicense.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libEllipticLicense.a; path = ../Builds/Release/libEllipticLicense.a; sourceTree = SOURCE_ROOT; }; 36 | 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 37 | 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 38 | 1DDD58290DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MyDocument.xib; sourceTree = ""; }; 39 | 1DDD582B0DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; 40 | 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyDocument.m; sourceTree = ""; }; 41 | 2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyDocument.h; sourceTree = ""; }; 42 | 2A37F4B0FDCFA73011CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 43 | 2A37F4BAFDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = ""; }; 44 | 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 45 | 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 46 | 32DBCF750370BD2300C91783 /* EllipticLicenseDeveloper_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EllipticLicenseDeveloper_Prefix.pch; sourceTree = ""; }; 47 | 8D15AC360486D014006FF6A4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 8D15AC370486D014006FF6A4 /* EllipticLicenseDeveloper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EllipticLicenseDeveloper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 8D15AC330486D014006FF6A4 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */, 57 | 0A85648E0F82C4DF00AEAB7A /* libEllipticLicense.a in Frameworks */, 58 | 0A76B9DB106FE1780048097B /* libcrypto.0.9.8.dylib in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 0A76B9DA106FE1780048097B /* libcrypto.0.9.8.dylib */, 69 | 0A85648D0F82C4DF00AEAB7A /* libEllipticLicense.a */, 70 | 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */, 71 | ); 72 | name = "Linked Frameworks"; 73 | sourceTree = ""; 74 | }; 75 | 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */, 79 | 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */, 80 | 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */, 81 | ); 82 | name = "Other Frameworks"; 83 | sourceTree = ""; 84 | }; 85 | 19C28FB0FE9D524F11CA2CBB /* Products */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 8D15AC370486D014006FF6A4 /* EllipticLicenseDeveloper.app */, 89 | ); 90 | name = Products; 91 | sourceTree = ""; 92 | }; 93 | 2A37F4AAFDCFA73011CA2CEA /* EllipticLicenseDeveloper */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 2A37F4ABFDCFA73011CA2CEA /* Classes */, 97 | 2A37F4AFFDCFA73011CA2CEA /* Other Sources */, 98 | 2A37F4B8FDCFA73011CA2CEA /* Resources */, 99 | 2A37F4C3FDCFA73011CA2CEA /* Frameworks */, 100 | 19C28FB0FE9D524F11CA2CBB /* Products */, 101 | ); 102 | name = EllipticLicenseDeveloper; 103 | sourceTree = ""; 104 | }; 105 | 2A37F4ABFDCFA73011CA2CEA /* Classes */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 0A855F0E0F81243600AEAB7A /* ProductStore.h */, 109 | 0A855F0F0F81243600AEAB7A /* ProductStore.m */, 110 | 2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */, 111 | 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */, 112 | 0A8563130F8181CC00AEAB7A /* AppController.h */, 113 | 0A8563140F8181CC00AEAB7A /* AppController.m */, 114 | ); 115 | name = Classes; 116 | sourceTree = ""; 117 | }; 118 | 2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 0A855DEC0F81050800AEAB7A /* EllipticLicense.h */, 122 | 32DBCF750370BD2300C91783 /* EllipticLicenseDeveloper_Prefix.pch */, 123 | 2A37F4B0FDCFA73011CA2CEA /* main.m */, 124 | ); 125 | name = "Other Sources"; 126 | sourceTree = ""; 127 | }; 128 | 2A37F4B8FDCFA73011CA2CEA /* Resources */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 0A8563C80F81922E00AEAB7A /* InvalidKey.png */, 132 | 0A8563C30F8191BB00AEAB7A /* ValidKey.png */, 133 | 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */, 134 | 8D15AC360486D014006FF6A4 /* Info.plist */, 135 | 089C165FFE840EACC02AAC07 /* InfoPlist.strings */, 136 | 1DDD58280DA1D0D100B32029 /* MyDocument.xib */, 137 | 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */, 138 | ); 139 | name = Resources; 140 | sourceTree = ""; 141 | }; 142 | 2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */, 146 | 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */, 147 | ); 148 | name = Frameworks; 149 | sourceTree = ""; 150 | }; 151 | /* End PBXGroup section */ 152 | 153 | /* Begin PBXNativeTarget section */ 154 | 8D15AC270486D014006FF6A4 /* EllipticLicenseDeveloper */ = { 155 | isa = PBXNativeTarget; 156 | buildConfigurationList = C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "EllipticLicenseDeveloper" */; 157 | buildPhases = ( 158 | 8D15AC2B0486D014006FF6A4 /* Resources */, 159 | 8D15AC300486D014006FF6A4 /* Sources */, 160 | 8D15AC330486D014006FF6A4 /* Frameworks */, 161 | ); 162 | buildRules = ( 163 | ); 164 | dependencies = ( 165 | ); 166 | name = EllipticLicenseDeveloper; 167 | productInstallPath = "$(HOME)/Applications"; 168 | productName = EllipticLicenseDeveloper; 169 | productReference = 8D15AC370486D014006FF6A4 /* EllipticLicenseDeveloper.app */; 170 | productType = "com.apple.product-type.application"; 171 | }; 172 | /* End PBXNativeTarget section */ 173 | 174 | /* Begin PBXProject section */ 175 | 2A37F4A9FDCFA73011CA2CEA /* Project object */ = { 176 | isa = PBXProject; 177 | buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "EllipticLicenseDeveloper" */; 178 | compatibilityVersion = "Xcode 3.1"; 179 | developmentRegion = English; 180 | hasScannedForEncodings = 1; 181 | knownRegions = ( 182 | English, 183 | Japanese, 184 | French, 185 | German, 186 | ); 187 | mainGroup = 2A37F4AAFDCFA73011CA2CEA /* EllipticLicenseDeveloper */; 188 | projectDirPath = ""; 189 | projectRoot = ""; 190 | targets = ( 191 | 8D15AC270486D014006FF6A4 /* EllipticLicenseDeveloper */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 8D15AC2B0486D014006FF6A4 /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */, 202 | 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */, 203 | 1DDD582C0DA1D0D100B32029 /* MyDocument.xib in Resources */, 204 | 1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */, 205 | 0A8563C40F8191BB00AEAB7A /* ValidKey.png in Resources */, 206 | 0A8563C90F81922E00AEAB7A /* InvalidKey.png in Resources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXResourcesBuildPhase section */ 211 | 212 | /* Begin PBXSourcesBuildPhase section */ 213 | 8D15AC300486D014006FF6A4 /* Sources */ = { 214 | isa = PBXSourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 8D15AC310486D014006FF6A4 /* MyDocument.m in Sources */, 218 | 8D15AC320486D014006FF6A4 /* main.m in Sources */, 219 | 0A855F100F81243600AEAB7A /* ProductStore.m in Sources */, 220 | 0A8563150F8181CC00AEAB7A /* AppController.m in Sources */, 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | /* End PBXSourcesBuildPhase section */ 225 | 226 | /* Begin PBXVariantGroup section */ 227 | 089C165FFE840EACC02AAC07 /* InfoPlist.strings */ = { 228 | isa = PBXVariantGroup; 229 | children = ( 230 | 089C1660FE840EACC02AAC07 /* English */, 231 | ); 232 | name = InfoPlist.strings; 233 | sourceTree = ""; 234 | }; 235 | 1DDD58280DA1D0D100B32029 /* MyDocument.xib */ = { 236 | isa = PBXVariantGroup; 237 | children = ( 238 | 1DDD58290DA1D0D100B32029 /* English */, 239 | ); 240 | name = MyDocument.xib; 241 | sourceTree = ""; 242 | }; 243 | 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */ = { 244 | isa = PBXVariantGroup; 245 | children = ( 246 | 1DDD582B0DA1D0D100B32029 /* English */, 247 | ); 248 | name = MainMenu.xib; 249 | sourceTree = ""; 250 | }; 251 | 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */ = { 252 | isa = PBXVariantGroup; 253 | children = ( 254 | 2A37F4BAFDCFA73011CA2CEA /* English */, 255 | ); 256 | name = Credits.rtf; 257 | sourceTree = ""; 258 | }; 259 | /* End PBXVariantGroup section */ 260 | 261 | /* Begin XCBuildConfiguration section */ 262 | C05733C808A9546B00998B17 /* Debug */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | ALWAYS_SEARCH_USER_PATHS = NO; 266 | COPY_PHASE_STRIP = NO; 267 | GCC_DYNAMIC_NO_PIC = NO; 268 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 269 | GCC_MODEL_TUNING = G5; 270 | GCC_OPTIMIZATION_LEVEL = 0; 271 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 272 | GCC_PREFIX_HEADER = EllipticLicenseDeveloper_Prefix.pch; 273 | INFOPLIST_FILE = Info.plist; 274 | INSTALL_PATH = "$(HOME)/Applications"; 275 | LIBRARY_SEARCH_PATHS = ( 276 | "$(inherited)", 277 | "\"$(SRCROOT)/../Builds/Release\"", 278 | ); 279 | PRODUCT_NAME = EllipticLicenseDeveloper; 280 | }; 281 | name = Debug; 282 | }; 283 | C05733C908A9546B00998B17 /* Release */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ALWAYS_SEARCH_USER_PATHS = NO; 287 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 288 | GCC_MODEL_TUNING = G5; 289 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 290 | GCC_PREFIX_HEADER = EllipticLicenseDeveloper_Prefix.pch; 291 | INFOPLIST_FILE = Info.plist; 292 | INSTALL_PATH = "$(HOME)/Applications"; 293 | LIBRARY_SEARCH_PATHS = ( 294 | "$(inherited)", 295 | "\"$(SRCROOT)/../Builds/Release\"", 296 | ); 297 | PRODUCT_NAME = EllipticLicenseDeveloper; 298 | }; 299 | name = Release; 300 | }; 301 | C05733CC08A9546B00998B17 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ARCHS = "$(NATIVE_ARCH)"; 305 | GCC_C_LANGUAGE_STANDARD = c99; 306 | GCC_OPTIMIZATION_LEVEL = 0; 307 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 308 | GCC_WARN_UNUSED_VARIABLE = YES; 309 | ONLY_ACTIVE_ARCH = YES; 310 | OTHER_LDFLAGS = ( 311 | "-all_load", 312 | "-ObjC", 313 | ); 314 | PREBINDING = NO; 315 | SDKROOT = macosx10.6; 316 | SYMROOT = ../Builds; 317 | }; 318 | name = Debug; 319 | }; 320 | C05733CD08A9546B00998B17 /* Release */ = { 321 | isa = XCBuildConfiguration; 322 | buildSettings = { 323 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 324 | GCC_C_LANGUAGE_STANDARD = c99; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 326 | GCC_WARN_UNUSED_VARIABLE = YES; 327 | OTHER_LDFLAGS = ( 328 | "-all_load", 329 | "-ObjC", 330 | ); 331 | PREBINDING = NO; 332 | SDKROOT = macosx10.6; 333 | SYMROOT = ../Builds; 334 | }; 335 | name = Release; 336 | }; 337 | /* End XCBuildConfiguration section */ 338 | 339 | /* Begin XCConfigurationList section */ 340 | C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "EllipticLicenseDeveloper" */ = { 341 | isa = XCConfigurationList; 342 | buildConfigurations = ( 343 | C05733C808A9546B00998B17 /* Debug */, 344 | C05733C908A9546B00998B17 /* Release */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Release; 348 | }; 349 | C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "EllipticLicenseDeveloper" */ = { 350 | isa = XCConfigurationList; 351 | buildConfigurations = ( 352 | C05733CC08A9546B00998B17 /* Debug */, 353 | C05733CD08A9546B00998B17 /* Release */, 354 | ); 355 | defaultConfigurationIsVisible = 0; 356 | defaultConfigurationName = Release; 357 | }; 358 | /* End XCConfigurationList section */ 359 | }; 360 | rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */; 361 | } 362 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/EllipticLicenseDeveloper_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'EllipticLicenseDeveloper' target in the 'EllipticLicenseDeveloper' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/English.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;\red74\green33\blue135;} 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc 5 | 6 | \f0\b\fs22 \cf0 Designed and developed by 7 | \b0 \ 8 | Dmitry Chestnykh\ 9 | \ 10 | \pard\pardeftab720\qc 11 | {\field{\*\fldinst{HYPERLINK "http://www.codingrobots.com/"}}{\fldrslt \cf2 http://www.codingrobots.com}}\ 12 | \ 13 | Copyright \'a9 2009 Coding Robots\ 14 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural 15 | \cf0 Distributed under {\field{\*\fldinst{HYPERLINK "http://www.opensource.org/licenses/mit-license.html"}}{\fldrslt the open source MIT License}}\ 16 | \ 17 | } -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/EllipticLicenseDeveloper/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeExtensions 11 | 12 | elproj 13 | 14 | CFBundleTypeName 15 | Elliptic License Developer Project 16 | CFBundleTypeRole 17 | Editor 18 | LSTypeIsPackage 19 | 20 | NSDocumentClass 21 | MyDocument 22 | NSPersistentStoreTypeKey 23 | XML 24 | 25 | 26 | CFBundleExecutable 27 | ${EXECUTABLE_NAME} 28 | CFBundleIconFile 29 | 30 | CFBundleIdentifier 31 | com.codingrobots.${PRODUCT_NAME:identifier} 32 | CFBundleInfoDictionaryVersion 33 | 6.0 34 | CFBundleName 35 | ${PRODUCT_NAME} 36 | CFBundlePackageType 37 | APPL 38 | CFBundleSignature 39 | ???? 40 | CFBundleVersion 41 | 1.0 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplication 46 | 47 | 48 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/InvalidKey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/EllipticLicenseDeveloper/InvalidKey.png -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/MyDocument.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocument.h 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 30.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import 22 | #import "ProductStore.h" 23 | 24 | @interface MyDocument : NSDocument 25 | { 26 | ProductStore *productStore; 27 | 28 | IBOutlet id licenseNameTextField; 29 | IBOutlet id licenseKeyTextField; 30 | IBOutlet id formattedLicenseTextView; 31 | IBOutlet id codeTextView; 32 | IBOutlet id codePopUpButton; 33 | 34 | IBOutlet id blockKeyWindow; 35 | IBOutlet id blockKeyTextField; 36 | IBOutlet id blockedKeysController; 37 | } 38 | 39 | @property (retain) ProductStore *productStore; 40 | - (IBAction)generateKeys:(id)sender; 41 | - (IBAction)generateLicenseKey:(id)sender; 42 | - (IBAction)verifyLicenseKey:(id)sender; 43 | - (IBAction)showCode:(id)sender; 44 | 45 | - (IBAction)addBlockedKey:(id)sender; 46 | - (IBAction)closeBlockKeySheet:(id)sender; 47 | - (IBAction)doAddBlockedKey:(id)sender; 48 | @end 49 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/MyDocument.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocument.m 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 30.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import "MyDocument.h" 22 | 23 | 24 | @implementation MyDocument 25 | @synthesize productStore; 26 | 27 | - (id)init; 28 | { 29 | self = [super init]; 30 | if (self) { 31 | 32 | // Add your subclass-specific initialization here. 33 | // If an error occurs here, send a [self release] message and return nil. 34 | [self setProductStore:[[[ProductStore alloc] init] autorelease]]; 35 | [self updateChangeCount:NSChangeDone]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)setProductStore:(ProductStore *)newStore; 41 | { 42 | if (productStore == newStore) 43 | return; 44 | [productStore removeObserver:self forKeyPath:@"blockedLicenseKeys"]; 45 | [productStore removeObserver:self forKeyPath:@"publicKey"]; 46 | [productStore removeObserver:self forKeyPath:@"numberOfCharactersInDashGroup"]; 47 | [productStore release]; 48 | productStore = [newStore retain]; 49 | [productStore addObserver:self forKeyPath:@"blockedLicenseKeys" options:NSKeyValueObservingOptionNew context:nil]; 50 | [productStore addObserver:self forKeyPath:@"publicKey" options:NSKeyValueObservingOptionNew context:nil]; 51 | [productStore addObserver:self forKeyPath:@"numberOfCharactersInDashGroup" options:NSKeyValueObservingOptionNew context:nil]; 52 | } 53 | 54 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; 55 | { 56 | if (object == productStore) { 57 | [self updateChangeCount:NSChangeDone]; 58 | } 59 | } 60 | 61 | 62 | - (NSString *)windowNibName; 63 | { 64 | // Override returning the nib file name of the document 65 | // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. 66 | return @"MyDocument"; 67 | } 68 | 69 | - (void)windowControllerDidLoadNib:(NSWindowController *) aController; 70 | { 71 | [super windowControllerDidLoadNib:aController]; 72 | // Add any code here that needs to be executed once the windowController has loaded the document's window. 73 | } 74 | 75 | - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError; 76 | { 77 | // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil. 78 | 79 | // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead. 80 | 81 | // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead. 82 | [productStore setIsLocked:YES]; 83 | NSMutableData *data = [[NSMutableData alloc] init]; 84 | NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 85 | [archiver setOutputFormat:NSPropertyListXMLFormat_v1_0]; 86 | [archiver encodeObject:productStore]; 87 | [archiver finishEncoding]; 88 | return [data autorelease]; 89 | 90 | if ( outError != NULL ) { 91 | *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; 92 | } 93 | return nil; 94 | } 95 | 96 | - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError 97 | { 98 | // Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO. 99 | 100 | // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. 101 | 102 | // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead. 103 | 104 | //[self setProductStore:[NSKeyedUnarchiver unarchiveObjectWithData:data]]; 105 | 106 | NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 107 | // Customize unarchiver here 108 | [self setProductStore:[unarchiver decodeObject]]; 109 | [unarchiver finishDecoding]; 110 | [unarchiver release]; 111 | [self updateChangeCount:NSChangeCleared]; 112 | 113 | if ( outError != NULL ) { 114 | *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; 115 | } 116 | return YES; 117 | } 118 | 119 | - (void)dealloc; 120 | { 121 | [self setProductStore:nil]; 122 | [super dealloc]; 123 | } 124 | 125 | #pragma mark - 126 | #pragma mark Actions 127 | 128 | - (IBAction)generateKeys:(id)sender; 129 | { 130 | [productStore generateKeys]; 131 | [productStore setIsLocked:YES]; 132 | } 133 | 134 | - (IBAction)generateLicenseKey:(id)sender; 135 | { 136 | NSString *name = [licenseNameTextField stringValue]; 137 | NSString *key = [productStore generateLicenseKeyForName:name]; 138 | [licenseKeyTextField setStringValue:key]; 139 | NSString *formatted = [NSString stringWithFormat:@"Licensed to: %@\nLicense key: %@", name, key]; 140 | //NSAttributedString *text = [[[NSAttributedString alloc] initWithString:formatted] autorelease]; 141 | //[[formattedLicenseTextView textStorage] setAttributedString:text]; 142 | [[formattedLicenseTextView textStorage] replaceCharactersInRange:NSMakeRange(0, [[formattedLicenseTextView textStorage] length]) withString:formatted]; 143 | } 144 | 145 | - (IBAction)verifyLicenseKey:(id)sender; 146 | { 147 | NSString *name = [licenseNameTextField stringValue]; 148 | NSString *key = [licenseKeyTextField stringValue]; 149 | 150 | NSAlert *alert; 151 | 152 | if ([[productStore ellipticLicense] isBlockedLicenseKey:key]) { 153 | alert = [NSAlert alertWithMessageText:@"Blocked key" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"This key is blocked."]; 154 | [alert setIcon:[NSImage imageNamed:@"InvalidKey"]]; 155 | [alert setAlertStyle:NSCriticalAlertStyle]; 156 | } 157 | else { 158 | if ([[productStore ellipticLicense] verifyLicenseKey:key forName:name]) { 159 | alert = [NSAlert alertWithMessageText:@"Valid key" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"This key is valid."]; 160 | [alert setIcon:[NSImage imageNamed:@"ValidKey"]]; 161 | } 162 | else { 163 | alert = [NSAlert alertWithMessageText:@"Invalid key" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"License name or key is invalid!"]; 164 | [alert setIcon:[NSImage imageNamed:@"InvalidKey"]]; 165 | } 166 | } 167 | [alert beginSheetModalForWindow:[sender window] modalDelegate:self didEndSelector:nil contextInfo:nil]; 168 | } 169 | 170 | - (IBAction)showCode:(id)sender; 171 | { 172 | NSMutableString *code; 173 | switch ([(NSPopUpButton *)sender selectedTag]) { 174 | case 0: // Obfuscated Public Key 175 | code = [NSMutableString stringWithString:[productStore obfuscatedPublicKeyCode]]; 176 | break; 177 | case 1: 178 | code = [NSMutableString stringWithString:[productStore blockedLicenseKeysAsCode]]; 179 | break; 180 | case 2: // Initialization Example 181 | { 182 | NSString *curveName; 183 | switch([productStore curveNameTag]) { 184 | case 0: curveName = @"ELCurveNameSecp112r1"; break; 185 | case 1: curveName = @"ELCurveNameSecp128r1"; break; 186 | case 2: curveName = @"ELCurveNameSecp160r1"; break; 187 | } 188 | code = [NSMutableString string]; 189 | [code appendFormat:@"#include \"EllipticLicense.h\"\n\n" 190 | "// ... somewhere inside a method of your class ... \n" 191 | "%@\n" 192 | "%@\n\n" 193 | "\tEllipticLicense *ellipticLicense = [[EllipticLicense alloc] initWithPublicKey:key curveName:%@];\n", [productStore obfuscatedPublicKeyCode], [productStore blockedLicenseKeysAsCode], curveName]; 194 | if ([[productStore blockedLicenseKeys] count] > 0) 195 | [code appendString:@"\t[ellipticLicense setBlockedKeys:blockedKeys];\n"]; 196 | 197 | [code appendString:@"\n\t// ... check licenses here ...\n\n" 198 | "\t[ellipticLicense release];\n"]; 199 | break; 200 | } 201 | case 3: 202 | { 203 | code = [NSMutableString string]; 204 | [code appendFormat:@"\n", [productStore curveName], [productStore publicKey], [productStore privateKey], [productStore numberOfCharactersInDashGroup]]; 217 | break; 218 | } 219 | } 220 | [[codeTextView textStorage] replaceCharactersInRange:NSMakeRange(0, [[codeTextView textStorage] length]) withString:code]; 221 | } 222 | 223 | - (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem; 224 | { 225 | if (![productStore isLocked]) { 226 | [productStore setIsLocked:YES]; 227 | [[NSSound soundNamed:@"Tink"] play]; 228 | //[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; 229 | } 230 | } 231 | 232 | - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem 233 | { 234 | if ([[tabViewItem identifier] isEqualToString:@"Code"]) 235 | [self showCode:codePopUpButton]; 236 | } 237 | 238 | - (IBAction)addBlockedKey:(id)sender; 239 | { 240 | [blockKeyTextField setStringValue:@""]; 241 | [NSApp beginSheet:blockKeyWindow modalForWindow:[sender window] modalDelegate:self didEndSelector:nil contextInfo:nil]; 242 | } 243 | 244 | 245 | - (IBAction)closeBlockKeySheet:(id)sender; 246 | { 247 | [NSApp endSheet:blockKeyWindow]; 248 | [blockKeyWindow orderOut:self]; 249 | } 250 | 251 | - (IBAction)doAddBlockedKey:(id)sender; 252 | { 253 | NSString *key = [blockKeyTextField stringValue]; 254 | if (!key || [key length] == 0) { 255 | NSBeep(); 256 | [self closeBlockKeySheet:self]; 257 | return; 258 | } 259 | 260 | NSMutableDictionary *blockDict = [NSMutableDictionary dictionary]; 261 | [blockDict setObject:key forKey:@"key"]; 262 | [blockDict setObject:[[productStore ellipticLicense] hashStringOfLicenseKey:key] forKey:@"hash"]; 263 | 264 | [blockedKeysController addObject:blockDict]; 265 | 266 | [self closeBlockKeySheet:self]; 267 | } 268 | 269 | @end 270 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/ProductStore.h: -------------------------------------------------------------------------------- 1 | // 2 | // ProductStore.h 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 30.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import 22 | #import "EllipticLicense.h" 23 | 24 | 25 | @interface ProductStore : NSObject { 26 | NSString *curveName; 27 | NSInteger curveNameTag; 28 | NSInteger numberOfCharactersInDashGroup; 29 | NSString *publicKey; 30 | NSString *privateKey; 31 | NSArray *blockedLicenseKeys; 32 | EllipticLicense *ellipticLicense; 33 | BOOL isLocked; 34 | NSString *obfuscatedPublicKeyCode; 35 | BOOL isChanged; 36 | } 37 | @property (copy) NSString *curveName; 38 | @property (assign) NSInteger curveNameTag; 39 | @property (assign) NSInteger numberOfCharactersInDashGroup; 40 | @property (copy) NSString *publicKey; 41 | @property (copy) NSString *privateKey; 42 | @property (retain) NSArray *blockedLicenseKeys; 43 | @property (copy, readonly) NSString *exampleLicenseKey; 44 | @property (retain) EllipticLicense *ellipticLicense; 45 | @property (assign) BOOL isLocked; 46 | @property (copy) NSString *obfuscatedPublicKeyCode; 47 | 48 | - (void)generateKeys; 49 | - (NSString *)generateLicenseKeyForName:(NSString *)name; 50 | - (NSString *)blockedLicenseKeysAsCode; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/ProductStore.m: -------------------------------------------------------------------------------- 1 | // 2 | // ProductStore.m 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 30.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #import "ProductStore.h" 22 | #import "EllipticLicense.h" 23 | 24 | NSString *exampleKeyString = @"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; 25 | 26 | @interface ProductStore (Private) 27 | - (NSString *)generateObfuscatedPublicKeyCode; 28 | @end 29 | 30 | 31 | @implementation ProductStore 32 | 33 | @synthesize curveName; 34 | @synthesize numberOfCharactersInDashGroup; 35 | @synthesize publicKey; 36 | @synthesize privateKey; 37 | @synthesize blockedLicenseKeys; 38 | @synthesize ellipticLicense; 39 | @synthesize isLocked; 40 | @synthesize obfuscatedPublicKeyCode; 41 | 42 | + (void)initialize; 43 | { 44 | srandom(time(NULL)); 45 | } 46 | 47 | - (id)init; 48 | { 49 | if (![super init]) 50 | return nil; 51 | ellipticLicense = [[EllipticLicense alloc] init]; 52 | [self setCurveName:ELCurveNameSecp112r1]; 53 | [self setBlockedLicenseKeys:[NSMutableArray array]]; 54 | return self; 55 | } 56 | 57 | - (id)initWithCoder:(NSCoder *)decoder; 58 | { 59 | if (![super init]) 60 | return nil; 61 | ellipticLicense = [[EllipticLicense alloc] init]; 62 | [self setCurveName:[decoder decodeObjectForKey:@"curveName"]]; 63 | [self setNumberOfCharactersInDashGroup:[decoder decodeIntegerForKey:@"numberOfCharactersInDashGroup"]]; 64 | [self setPrivateKey:[decoder decodeObjectForKey:@"privateKey"]]; 65 | [self setPublicKey:[decoder decodeObjectForKey:@"publicKey"]]; 66 | [self setBlockedLicenseKeys:[decoder decodeObjectForKey:@"blockedLicenseKeys"]]; 67 | [self setObfuscatedPublicKeyCode:[decoder decodeObjectForKey:@"obfuscatedPublicKeyCode"]]; 68 | [self setIsLocked:YES]; // do not decode this, just put yes 69 | 70 | [ellipticLicense setPublicKey:[self publicKey] privateKey:[self privateKey]]; 71 | 72 | return self; 73 | } 74 | 75 | - (void)encodeWithCoder:(NSCoder *)encoder; 76 | { 77 | [encoder encodeObject:curveName forKey:@"curveName"]; 78 | [encoder encodeInteger:numberOfCharactersInDashGroup forKey:@"numberOfCharactersInDashGroup"]; 79 | [encoder encodeObject:publicKey forKey:@"publicKey"]; 80 | [encoder encodeObject:privateKey forKey:@"privateKey"]; 81 | [encoder encodeObject:blockedLicenseKeys forKey:@"blockedLicenseKeys"]; 82 | [encoder encodeObject:obfuscatedPublicKeyCode forKey:@"obfuscatedPublicKeyCode"]; 83 | [encoder encodeBool:isLocked forKey:@"isLocked"]; 84 | } 85 | 86 | - (void)dealloc; 87 | { 88 | [curveName release]; 89 | [publicKey release]; 90 | [privateKey release]; 91 | [blockedLicenseKeys release]; 92 | [ellipticLicense release]; 93 | [super dealloc]; 94 | } 95 | 96 | - (NSInteger)curveNameTag; 97 | { 98 | if ([[self curveName] isEqualToString:ELCurveNameSecp112r1]) 99 | return 0; 100 | else if ([[self curveName] isEqualToString:ELCurveNameSecp128r1]) 101 | return 1; 102 | else if ([[self curveName] isEqualToString:ELCurveNameSecp160r1]) 103 | return 2; 104 | else 105 | return 0; 106 | } 107 | 108 | - (void)setCurveNameTag:(NSInteger)tag; 109 | { 110 | [self willChangeValueForKey:@"curveNameTag"]; 111 | switch (tag) { 112 | case 0 : [self setCurveName:ELCurveNameSecp112r1]; break; 113 | case 1 : [self setCurveName:ELCurveNameSecp128r1]; break; 114 | case 2 : [self setCurveName:ELCurveNameSecp160r1]; break; 115 | }; 116 | [self didChangeValueForKey:@"curveNameTag"]; 117 | } 118 | 119 | - (void)setCurveName:(NSString *)name; 120 | { 121 | [self willChangeValueForKey:@"curveName"]; 122 | [self willChangeValueForKey:@"exampleLicenseKey"]; 123 | if (curveName == name) 124 | return; 125 | [curveName release]; 126 | curveName = [name copy]; 127 | [ellipticLicense setCurveName:curveName]; 128 | [self setNumberOfCharactersInDashGroup:[ellipticLicense numberOfDashGroupCharacters]]; 129 | [self didChangeValueForKey:@"exampleLicenseKey"]; 130 | [self didChangeValueForKey:@"curveName"]; 131 | [self generateKeys]; 132 | } 133 | 134 | - (void)setNumberOfCharactersInDashGroup:(NSInteger)number; 135 | { 136 | [self willChangeValueForKey:@"numberOfCharactersInDashGroup"]; 137 | [self willChangeValueForKey:@"exampleLicenseKey"]; 138 | numberOfCharactersInDashGroup = number; 139 | [ellipticLicense setNumberOfDashGroupCharacters:number]; 140 | [self didChangeValueForKey:@"exampleLicenseKey"]; 141 | [self didChangeValueForKey:@"numberOfCharactersInDashGroup"]; 142 | } 143 | 144 | - (NSString *)stringSeparatedWithDashes:(NSString *)string numberOfCharactersInGroup:(NSInteger)number; 145 | { 146 | if (number == 0) 147 | return [[string copy] autorelease]; 148 | NSMutableString *result = [string mutableCopy]; 149 | int i = number; 150 | while (i < [result length]) { 151 | [result insertString:@"-" atIndex:i]; 152 | i += number + 1; 153 | } 154 | return [result autorelease]; 155 | } 156 | 157 | - (NSString *)exampleLicenseKey; 158 | { 159 | NSUInteger keyLength; 160 | switch ([self curveNameTag]) { 161 | case 0: keyLength = 45; break; 162 | case 1: keyLength = 52; break; 163 | case 2: keyLength = 64; break; 164 | } 165 | 166 | NSString *exampleKey = [exampleKeyString substringToIndex:keyLength]; 167 | return [self stringSeparatedWithDashes:exampleKey numberOfCharactersInGroup:[self numberOfCharactersInDashGroup]]; 168 | } 169 | 170 | - (void)setBlockedLicenseKeys:(NSArray *)keys; 171 | { 172 | [self willChangeValueForKey:@"blockedLicenseKeys"]; 173 | if (blockedLicenseKeys == keys) 174 | return; 175 | NSMutableArray *hashes = [NSMutableArray array]; 176 | for (id obj in keys) { 177 | [hashes addObject:[obj objectForKey:@"hash"]]; 178 | } 179 | if ([hashes count] > 0) 180 | [ellipticLicense setBlockedLicenseKeyHashes:hashes]; 181 | 182 | [blockedLicenseKeys release]; 183 | blockedLicenseKeys = [keys retain]; 184 | [self didChangeValueForKey:@"blockedLicenseKeys"]; 185 | } 186 | 187 | #pragma mark - 188 | 189 | - (void)generateKeys; 190 | { 191 | if (![ellipticLicense generateKeys]) 192 | return; //show error 193 | [self setPublicKey:[ellipticLicense publicKey]]; 194 | [self setPrivateKey:[ellipticLicense privateKey]]; 195 | [self setObfuscatedPublicKeyCode:[self generateObfuscatedPublicKeyCode]]; 196 | [self setBlockedLicenseKeys:[NSMutableArray array]]; 197 | } 198 | 199 | - (NSString *)generateLicenseKeyForName:(NSString *)name; 200 | { 201 | if (![self isLocked]) 202 | [self setIsLocked:YES]; 203 | return [ellipticLicense licenseKeyForName:name]; 204 | } 205 | 206 | #pragma mark - 207 | 208 | - (NSString *)generateObfuscatedPublicKeyCode; 209 | { 210 | NSMutableString *code = [NSMutableString string]; 211 | [code appendString:@"\n" 212 | "\t//*** Begin Public Key ***\n" 213 | "\tNSMutableString *key = [NSMutableString string];\n"]; 214 | 215 | NSString *key = [self publicKey]; 216 | NSInteger keyLength = [key length]; 217 | NSRange range = NSMakeRange(0, 0); 218 | range.length += (random() % (keyLength/4-2)) + 1; 219 | do { 220 | [code appendFormat:@"\t[key appendString:@\"%@\"];\n", [key substringWithRange:range]]; 221 | range.location += range.length; 222 | range.length = (random() % (keyLength/4-2)) + 1; 223 | } while (range.location + range.length < keyLength); 224 | 225 | range.length = keyLength - range.location; 226 | [code appendFormat:@"\t[key appendString:@\"%@\"];\n", [key substringWithRange:range]]; 227 | 228 | [code appendString:@"\t// *** End Public Key ***\n"]; 229 | return code; 230 | } 231 | 232 | - (NSString *)blockedLicenseKeysAsCode; 233 | { 234 | if ([[self blockedLicenseKeys] count] == 0) 235 | return @"\t// No blocked keys"; 236 | NSMutableString *code = [NSMutableString string]; 237 | [code appendString:@"\n" 238 | "\t//*** Begin Blocked Keys ***\n" 239 | "\tNSMutableArray *blockedKeys = [NSMutableArray array];\n"]; 240 | for (id obj in [self blockedLicenseKeys]) { 241 | [code appendFormat:@"\t// Key: %@\n", [obj objectForKey:@"key"]]; 242 | [code appendFormat:@"\t[blockedKeys addObject:@\"%@\"];\n", [obj objectForKey:@"hash"]]; 243 | } 244 | [code appendString:@"\t// *** End Blocked Keys ***\n"]; 245 | return code; 246 | } 247 | 248 | @end 249 | -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/ValidKey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/EllipticLicenseDeveloper/ValidKey.png -------------------------------------------------------------------------------- /EllipticLicenseDeveloper/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // EllipticLicenseDeveloper 4 | // 5 | // Created by Dmitry Chestnykh on 30.03.09. 6 | // 7 | 8 | #import 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | return NSApplicationMain(argc, (const char **) argv); 13 | } 14 | -------------------------------------------------------------------------------- /Framework/EllipticLicense.h: -------------------------------------------------------------------------------- 1 | // 2 | // EllipticLicense.h 3 | // EllipticLicense 4 | // 5 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | 19 | #import 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | NSString *ELCurveNameSecp112r1 = @"secp112r1"; 27 | NSString *ELCurveNameSecp128r1 = @"secp128r1"; 28 | NSString *ELCurveNameSecp160r1 = @"secp160r1"; 29 | 30 | @interface EllipticLicense : NSObject { 31 | EC_KEY *ecKey; 32 | 33 | NSArray *blockedLicenseKeyHashes; // List of SHA-1 hashes of blocked license keys (without dashes). Use hashStringOfLicenseKey to get proper hash. Use setBlockedLicenseKeyHashes to set it. 34 | 35 | unsigned int numberOfDashGroupCharacters; // number of characters in groups in final license key (xxxxx-xxxxx-...) 36 | 37 | unsigned int curveName; // (internal) name of curve. Use setCurveName to set it with ELCurveName* strings. Default is ELCurveNameSecp112r1 (SECG/WTLS curve over a 112 bit prime field) 38 | 39 | unsigned int digestLength; // (internal) Length of SHA-1 digest used for signature. Can be less than the real length of SHA-1 for less than 160-bit curves: in this case we'll cut SHA-1 to digestLength. Changes with setCurveName. 40 | 41 | unsigned int base32signatureLength; // (internal) length of signature without dashes. Changes with setCurveName. 42 | } 43 | 44 | - (id)initWithPublicKey:(NSString *)publicKey; 45 | - (id)initWithPublicKey:(NSString *)publicKey curveName:(NSString *)curve; 46 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 47 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey curveName:(NSString *)curve; 48 | - (void)setCurveName:(NSString *)name; 49 | - (void)setNumberOfDashGroupCharacters:(unsigned int)number; 50 | - (unsigned int)numberOfDashGroupCharacters; 51 | 52 | - (BOOL)setPublicKey:(NSString *)publicKey; 53 | - (BOOL)setPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 54 | - (NSString *)privateKey; 55 | - (NSString *)publicKey; 56 | 57 | @property(retain) NSArray *blockedLicenseKeyHashes; 58 | - (BOOL)isBlockedLicenseKey:(NSString *)licenseKey; 59 | 60 | - (BOOL)generateKeys; 61 | - (void)logKeys; 62 | 63 | - (NSString *)hashStringOfLicenseKey:(NSString *)licenseKey; 64 | 65 | - (NSString *)licenseKeyForName:(NSString *)name; 66 | - (BOOL)verifyLicenseKey:(NSString *)signature forName:(NSString *)name; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Framework/EllipticLicense.m: -------------------------------------------------------------------------------- 1 | // 2 | // EllipticLicense.m 3 | // EllipticLicense 4 | // 5 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | 19 | #import "EllipticLicense.h" 20 | #import "NSData+ELAdditions.h" 21 | #include 22 | #include 23 | 24 | @interface EllipticLicense (Private) 25 | - (NSString *)stringSeparatedWithDashes:(NSString *)string; 26 | - (NSString *)cleanKeyFromLicenseKey:(NSString *)licenseKey; 27 | @end 28 | 29 | 30 | @implementation EllipticLicense 31 | 32 | @synthesize blockedLicenseKeyHashes; 33 | 34 | + (void)initialization; 35 | { 36 | ERR_load_crypto_strings(); 37 | } 38 | 39 | - (id)init; 40 | { 41 | if (![super init]) 42 | return nil; 43 | [self setCurveName:ELCurveNameSecp112r1]; // Set default curve 44 | return self; 45 | } 46 | 47 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey curveName:(NSString *)curve; 48 | { 49 | if (![self init]) 50 | return nil; 51 | if (curveName) 52 | [self setCurveName:curve]; 53 | if (![self setPublicKey:publicKey privateKey:privateKey]) 54 | return nil; 55 | return self; 56 | } 57 | 58 | - (id)initWithPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 59 | { 60 | return [self initWithPublicKey:publicKey privateKey:privateKey curveName:nil]; 61 | } 62 | 63 | - (id)initWithPublicKey:(NSString *)publicKey curveName:(NSString *)curve; 64 | { 65 | return [self initWithPublicKey:publicKey privateKey:nil curveName:curve]; 66 | } 67 | 68 | - (id)initWithPublicKey:(NSString *)publicKey; 69 | { 70 | return [self initWithPublicKey:publicKey curveName:nil]; 71 | } 72 | 73 | 74 | - (void)setCurveName:(NSString *)name; 75 | { 76 | if ([name isEqualToString:ELCurveNameSecp160r1]) { 77 | curveName = NID_secp160r1; 78 | digestLength = 20; // Full SHA-1 length 79 | base32signatureLength = 64; 80 | numberOfDashGroupCharacters = 8; 81 | } 82 | else if ([name isEqualToString:ELCurveNameSecp128r1]) { 83 | curveName = NID_secp128r1; 84 | digestLength = 16; // SHA-1 is 20 bytes, but since we use 16-byte curve, we must crop it 85 | base32signatureLength = 52; 86 | numberOfDashGroupCharacters = 4; 87 | } 88 | else { // default is ELCurveNameSecp112r1 89 | curveName = NID_secp112r1; 90 | digestLength = 14; // SHA-1 is 20 bytes, but since we use 14-byte curve, we must crop it 91 | base32signatureLength = 45; 92 | numberOfDashGroupCharacters = 5; 93 | } 94 | } 95 | 96 | - (void)setNumberOfDashGroupCharacters:(unsigned int)number; 97 | { 98 | numberOfDashGroupCharacters = number; 99 | } 100 | 101 | - (unsigned int)numberOfDashGroupCharacters; 102 | { 103 | return numberOfDashGroupCharacters; 104 | } 105 | 106 | - (BOOL)setPublicKey:(NSString *)publicKey; 107 | { 108 | return [self setPublicKey:publicKey privateKey:nil]; 109 | } 110 | 111 | - (BOOL)setPublicKey:(NSString *)publicKey privateKey:(NSString *)privateKey; 112 | { 113 | if (ecKey) 114 | EC_KEY_free(ecKey); 115 | ecKey = EC_KEY_new_by_curve_name(curveName); 116 | if (ecKey == NULL) 117 | return NO; 118 | 119 | NSData *publicKeyData = [NSData el_dataWithHexString:publicKey]; 120 | const unsigned char *pubBytes = [publicKeyData bytes]; 121 | ecKey = o2i_ECPublicKey(&ecKey, &pubBytes, [publicKeyData length]); 122 | if (ecKey == NULL) 123 | return NO; 124 | 125 | if (privateKey) { 126 | NSData *privateKeyData = [NSData el_dataWithHexString:privateKey]; 127 | const unsigned char *privBytes = [privateKeyData bytes]; 128 | ecKey = d2i_ECPrivateKey(&ecKey, &privBytes, [privateKeyData length]); 129 | if (ecKey == NULL) 130 | return NO; 131 | } 132 | return (EC_KEY_check_key(ecKey)); 133 | } 134 | 135 | 136 | - (BOOL)generateKeys; 137 | { 138 | if (ecKey) 139 | EC_KEY_free(ecKey); 140 | ecKey = EC_KEY_new_by_curve_name(curveName); 141 | if (!ecKey) 142 | return NO; 143 | return EC_KEY_generate_key(ecKey); 144 | } 145 | 146 | - (NSString *)publicKey; 147 | { 148 | unsigned char *bytes = NULL; 149 | int length = i2o_ECPublicKey(ecKey, &bytes); 150 | return [[NSData dataWithBytesNoCopy:bytes length:length] el_hexString]; 151 | } 152 | 153 | - (NSString *)privateKey; 154 | { 155 | unsigned char *bytes = NULL; 156 | int length = i2d_ECPrivateKey(ecKey, &bytes); 157 | return [[NSData dataWithBytesNoCopy:bytes length:length] el_hexString]; 158 | } 159 | 160 | - (NSString *)licenseKeyForName:(NSString *)name; 161 | { 162 | NSData *digest = [[NSData el_dataWithStringNoNull:name] el_sha1Digest]; 163 | if (!digest) 164 | return nil; 165 | ECDSA_SIG *signature = ECDSA_do_sign([digest bytes], digestLength, ecKey); 166 | if (signature == NULL) 167 | return nil; 168 | 169 | size_t rlen = BN_num_bytes(signature->r); 170 | size_t slen = BN_num_bytes(signature->s); 171 | unsigned char *signatureBytes = OPENSSL_malloc(rlen+slen); 172 | BN_bn2bin(signature->r, signatureBytes); 173 | BN_bn2bin(signature->s, signatureBytes+rlen); // join two values into signatureBytes 174 | NSMutableData *signatureData = [NSMutableData dataWithBytesNoCopy:signatureBytes length:rlen+slen]; 175 | 176 | return [self stringSeparatedWithDashes:[signatureData el_base32String]]; 177 | } 178 | 179 | - (BOOL)verifyLicenseKey:(NSString *)licenseKey forName:(NSString *)name; 180 | { 181 | if (!name || [name length] == 0) 182 | return NO; 183 | 184 | NSString *cleanKey = [self cleanKeyFromLicenseKey:licenseKey]; 185 | 186 | // Check length of signature before decoding 187 | if ([cleanKey length] != base32signatureLength) 188 | return NO; 189 | 190 | // Check if license key is blocked. Note that we use key without dashes 191 | if ([self isBlockedLicenseKey:cleanKey]) 192 | return NO; 193 | 194 | ECDSA_SIG *signature = ECDSA_SIG_new(); 195 | if (!signature) 196 | return NO; 197 | 198 | NSData *signatureData = [NSData el_dataWithBase32String:cleanKey]; 199 | size_t partLen = [signatureData length]/2; 200 | signature->r = BN_bin2bn([signatureData bytes], partLen, signature->r); 201 | signature->s = BN_bin2bn([signatureData bytes] + partLen, partLen, signature->s); 202 | if (!signature->r || !signature->s) { 203 | ECDSA_SIG_free(signature); 204 | return NO; 205 | } 206 | NSData *digest = [[NSData el_dataWithStringNoNull:name] el_sha1Digest]; 207 | if ([digest length] < digestLength) { 208 | ECDSA_SIG_free(signature); 209 | return NO; 210 | } 211 | BOOL result = ECDSA_do_verify([digest bytes], digestLength, signature, ecKey); 212 | 213 | ECDSA_SIG_free(signature); 214 | return result; 215 | } 216 | 217 | - (NSString *)hashStringOfLicenseKey:(NSString *)licenseKey; 218 | { 219 | NSString *cleanLicense = [self cleanKeyFromLicenseKey:licenseKey]; 220 | return [[NSData el_dataWithStringNoNull:cleanLicense] el_sha1DigestString]; 221 | } 222 | 223 | - (BOOL)isBlockedLicenseKey:(NSString *)licenseKey; 224 | { 225 | if (!blockedLicenseKeyHashes) 226 | return NO; 227 | return [blockedLicenseKeyHashes containsObject:[self hashStringOfLicenseKey:licenseKey]]; 228 | } 229 | 230 | - (void)logKeys; 231 | { 232 | NSLog(@"Public Key:\n%@", [self publicKey]); 233 | NSLog(@"Private Key:\n%@", [self privateKey]); 234 | } 235 | 236 | - (void)dealloc; 237 | { 238 | ERR_free_strings(); 239 | if (ecKey) 240 | EC_KEY_free(ecKey); 241 | [super dealloc]; 242 | } 243 | 244 | - (void)finalize; 245 | { 246 | ERR_free_strings(); 247 | if (ecKey) 248 | EC_KEY_free(ecKey); 249 | [super finalize]; 250 | } 251 | 252 | @end 253 | 254 | @implementation EllipticLicense (Private) 255 | 256 | - (NSString *)stringSeparatedWithDashes:(NSString *)string; 257 | { 258 | if (numberOfDashGroupCharacters == 0) 259 | return [[string copy] autorelease]; 260 | NSMutableString *result = [string mutableCopy]; 261 | int i = numberOfDashGroupCharacters; 262 | while (i < [result length]) { 263 | [result insertString:@"-" atIndex:i]; 264 | i += numberOfDashGroupCharacters + 1; 265 | } 266 | return [result autorelease]; 267 | } 268 | 269 | 270 | - (NSString *)cleanKeyFromLicenseKey:(NSString *)licenseKey; 271 | { 272 | NSMutableString *cleanKey = [licenseKey mutableCopy]; 273 | [cleanKey replaceOccurrencesOfString:@"-" withString:@"" options:0 range:NSMakeRange(0, [cleanKey length])]; 274 | // Fix wrong characters that are not in base32, but can be mistakened // Workaround, better fix base32 decoding to include this 275 | [cleanKey replaceOccurrencesOfString:@"0" withString:@"O" options:0 range:NSMakeRange(0, [cleanKey length])]; 276 | [cleanKey replaceOccurrencesOfString:@"1" withString:@"I" options:0 range:NSMakeRange(0, [cleanKey length])]; 277 | [cleanKey replaceOccurrencesOfString:@"8" withString:@"B" options:0 range:NSMakeRange(0, [cleanKey length])]; 278 | return [cleanKey autorelease]; 279 | } 280 | 281 | @end 282 | 283 | -------------------------------------------------------------------------------- /Framework/EllipticLicense.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/Framework/EllipticLicense.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /Framework/EllipticLicense.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A3676A60F7D1A0100B4662A /* EllipticLicense.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A3676A40F7D1A0100B4662A /* EllipticLicense.h */; }; 11 | 0A3676A70F7D1A0100B4662A /* EllipticLicense.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A3676A50F7D1A0100B4662A /* EllipticLicense.m */; }; 12 | 0A76B9B5106FDF330048097B /* libcrypto.0.9.8.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A76B9B4106FDF330048097B /* libcrypto.0.9.8.dylib */; }; 13 | 0A855A1B0F7EBA4F00AEAB7A /* NSData+ELAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A855A190F7EBA4F00AEAB7A /* NSData+ELAdditions.h */; }; 14 | 0A855A1C0F7EBA4F00AEAB7A /* NSData+ELAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A855A1A0F7EBA4F00AEAB7A /* NSData+ELAdditions.m */; }; 15 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 16 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 21 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 22 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 23 | 0A3676A40F7D1A0100B4662A /* EllipticLicense.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EllipticLicense.h; sourceTree = ""; }; 24 | 0A3676A50F7D1A0100B4662A /* EllipticLicense.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EllipticLicense.m; sourceTree = ""; }; 25 | 0A76B9B4106FDF330048097B /* libcrypto.0.9.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.0.9.8.dylib; path = /usr/lib/libcrypto.0.9.8.dylib; sourceTree = ""; }; 26 | 0A855A190F7EBA4F00AEAB7A /* NSData+ELAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+ELAdditions.h"; sourceTree = ""; }; 27 | 0A855A1A0F7EBA4F00AEAB7A /* NSData+ELAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+ELAdditions.m"; sourceTree = ""; }; 28 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 29 | 32DBCF5E0370ADEE00C91783 /* EllipticLicense_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EllipticLicense_Prefix.pch; sourceTree = ""; }; 30 | 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 8DC2EF5B0486A6940098B216 /* EllipticLicense.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = EllipticLicense.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 41 | 0A76B9B5106FDF330048097B /* libcrypto.0.9.8.dylib in Frameworks */, 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 034768DFFF38A50411DB9C8B /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 8DC2EF5B0486A6940098B216 /* EllipticLicense.framework */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 0867D691FE84028FC02AAC07 /* EllipticLicense */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 08FB77AEFE84172EC02AAC07 /* Classes */, 60 | 32C88DFF0371C24200C91783 /* Other Sources */, 61 | 089C1665FE841158C02AAC07 /* Resources */, 62 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 63 | 034768DFFF38A50411DB9C8B /* Products */, 64 | ); 65 | name = EllipticLicense; 66 | sourceTree = ""; 67 | }; 68 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 72 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 73 | ); 74 | name = "External Frameworks and Libraries"; 75 | sourceTree = ""; 76 | }; 77 | 089C1665FE841158C02AAC07 /* Resources */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 8DC2EF5A0486A6940098B216 /* Info.plist */, 81 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 82 | ); 83 | name = Resources; 84 | sourceTree = ""; 85 | }; 86 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 0A855A190F7EBA4F00AEAB7A /* NSData+ELAdditions.h */, 90 | 0A855A1A0F7EBA4F00AEAB7A /* NSData+ELAdditions.m */, 91 | 0A3676A40F7D1A0100B4662A /* EllipticLicense.h */, 92 | 0A3676A50F7D1A0100B4662A /* EllipticLicense.m */, 93 | ); 94 | name = Classes; 95 | sourceTree = ""; 96 | }; 97 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 0A76B9B4106FDF330048097B /* libcrypto.0.9.8.dylib */, 101 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 102 | ); 103 | name = "Linked Frameworks"; 104 | sourceTree = ""; 105 | }; 106 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 110 | D2F7E79907B2D74100F64583 /* CoreData.framework */, 111 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 112 | ); 113 | name = "Other Frameworks"; 114 | sourceTree = ""; 115 | }; 116 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 32DBCF5E0370ADEE00C91783 /* EllipticLicense_Prefix.pch */, 120 | ); 121 | name = "Other Sources"; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXHeadersBuildPhase section */ 127 | 8DC2EF500486A6940098B216 /* Headers */ = { 128 | isa = PBXHeadersBuildPhase; 129 | buildActionMask = 2147483647; 130 | files = ( 131 | 0A3676A60F7D1A0100B4662A /* EllipticLicense.h in Headers */, 132 | 0A855A1B0F7EBA4F00AEAB7A /* NSData+ELAdditions.h in Headers */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXHeadersBuildPhase section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | 8DC2EF4F0486A6940098B216 /* EllipticLicense */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "EllipticLicense" */; 142 | buildPhases = ( 143 | 8DC2EF500486A6940098B216 /* Headers */, 144 | 8DC2EF520486A6940098B216 /* Resources */, 145 | 8DC2EF540486A6940098B216 /* Sources */, 146 | 8DC2EF560486A6940098B216 /* Frameworks */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = EllipticLicense; 153 | productInstallPath = "$(HOME)/Library/Frameworks"; 154 | productName = EllipticLicense; 155 | productReference = 8DC2EF5B0486A6940098B216 /* EllipticLicense.framework */; 156 | productType = "com.apple.product-type.framework"; 157 | }; 158 | /* End PBXNativeTarget section */ 159 | 160 | /* Begin PBXProject section */ 161 | 0867D690FE84028FC02AAC07 /* Project object */ = { 162 | isa = PBXProject; 163 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "EllipticLicense" */; 164 | compatibilityVersion = "Xcode 3.1"; 165 | developmentRegion = English; 166 | hasScannedForEncodings = 1; 167 | knownRegions = ( 168 | English, 169 | Japanese, 170 | French, 171 | German, 172 | ); 173 | mainGroup = 0867D691FE84028FC02AAC07 /* EllipticLicense */; 174 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 175 | projectDirPath = ""; 176 | projectRoot = ""; 177 | targets = ( 178 | 8DC2EF4F0486A6940098B216 /* EllipticLicense */, 179 | ); 180 | }; 181 | /* End PBXProject section */ 182 | 183 | /* Begin PBXResourcesBuildPhase section */ 184 | 8DC2EF520486A6940098B216 /* Resources */ = { 185 | isa = PBXResourcesBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXResourcesBuildPhase section */ 193 | 194 | /* Begin PBXSourcesBuildPhase section */ 195 | 8DC2EF540486A6940098B216 /* Sources */ = { 196 | isa = PBXSourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 0A3676A70F7D1A0100B4662A /* EllipticLicense.m in Sources */, 200 | 0A855A1C0F7EBA4F00AEAB7A /* NSData+ELAdditions.m in Sources */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXSourcesBuildPhase section */ 205 | 206 | /* Begin PBXVariantGroup section */ 207 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 208 | isa = PBXVariantGroup; 209 | children = ( 210 | 089C1667FE841158C02AAC07 /* English */, 211 | ); 212 | name = InfoPlist.strings; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXVariantGroup section */ 216 | 217 | /* Begin XCBuildConfiguration section */ 218 | 1DEB91AE08733DA50010E9CD /* Debug */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | COPY_PHASE_STRIP = NO; 223 | DYLIB_COMPATIBILITY_VERSION = 1; 224 | DYLIB_CURRENT_VERSION = 1; 225 | FRAMEWORK_VERSION = A; 226 | GCC_DYNAMIC_NO_PIC = NO; 227 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 228 | GCC_MODEL_TUNING = G5; 229 | GCC_OPTIMIZATION_LEVEL = 0; 230 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 231 | GCC_PREFIX_HEADER = EllipticLicense_Prefix.pch; 232 | INFOPLIST_FILE = Info.plist; 233 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 234 | LIBRARY_SEARCH_PATHS = ( 235 | "$(inherited)", 236 | "\"$(SRCROOT)/../lib\"", 237 | ); 238 | PRODUCT_NAME = EllipticLicense; 239 | WRAPPER_EXTENSION = framework; 240 | }; 241 | name = Debug; 242 | }; 243 | 1DEB91AF08733DA50010E9CD /* Release */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | ALWAYS_SEARCH_USER_PATHS = NO; 247 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 248 | DYLIB_COMPATIBILITY_VERSION = 1; 249 | DYLIB_CURRENT_VERSION = 1; 250 | FRAMEWORK_VERSION = A; 251 | GCC_MODEL_TUNING = G5; 252 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 253 | GCC_PREFIX_HEADER = EllipticLicense_Prefix.pch; 254 | INFOPLIST_FILE = Info.plist; 255 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 256 | LIBRARY_SEARCH_PATHS = ( 257 | "$(inherited)", 258 | "\"$(SRCROOT)/../lib\"", 259 | ); 260 | PRODUCT_NAME = EllipticLicense; 261 | WRAPPER_EXTENSION = framework; 262 | }; 263 | name = Release; 264 | }; 265 | 1DEB91B208733DA50010E9CD /* Debug */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 269 | GCC_C_LANGUAGE_STANDARD = c99; 270 | GCC_ENABLE_OBJC_GC = supported; 271 | GCC_OPTIMIZATION_LEVEL = 0; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 273 | GCC_WARN_UNUSED_VARIABLE = YES; 274 | HEADER_SEARCH_PATHS = "../openssl/include/**"; 275 | INSTALL_PATH = ""; 276 | ONLY_ACTIVE_ARCH = YES; 277 | PREBINDING = NO; 278 | SDKROOT = macosx10.6; 279 | SYMROOT = ../Builds/; 280 | }; 281 | name = Debug; 282 | }; 283 | 1DEB91B308733DA50010E9CD /* Release */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 287 | GCC_C_LANGUAGE_STANDARD = c99; 288 | GCC_ENABLE_OBJC_GC = supported; 289 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | HEADER_SEARCH_PATHS = "../openssl/include/**"; 292 | INSTALL_PATH = ""; 293 | PREBINDING = NO; 294 | SDKROOT = macosx10.6; 295 | SYMROOT = ../Builds/; 296 | }; 297 | name = Release; 298 | }; 299 | /* End XCBuildConfiguration section */ 300 | 301 | /* Begin XCConfigurationList section */ 302 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "EllipticLicense" */ = { 303 | isa = XCConfigurationList; 304 | buildConfigurations = ( 305 | 1DEB91AE08733DA50010E9CD /* Debug */, 306 | 1DEB91AF08733DA50010E9CD /* Release */, 307 | ); 308 | defaultConfigurationIsVisible = 0; 309 | defaultConfigurationName = Release; 310 | }; 311 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "EllipticLicense" */ = { 312 | isa = XCConfigurationList; 313 | buildConfigurations = ( 314 | 1DEB91B208733DA50010E9CD /* Debug */, 315 | 1DEB91B308733DA50010E9CD /* Release */, 316 | ); 317 | defaultConfigurationIsVisible = 0; 318 | defaultConfigurationName = Release; 319 | }; 320 | /* End XCConfigurationList section */ 321 | }; 322 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 323 | } 324 | -------------------------------------------------------------------------------- /Framework/EllipticLicense_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'EllipticLicense' target in the 'EllipticLicense' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Framework/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/Framework/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /Framework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.codingrobots.${PRODUCT_NAME:identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | FMWK 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.1 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Framework/NSData+ELAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+ELAdditions.h 3 | // EllipticLicense 4 | // 5 | // Created by Dmitry Chestnykh on 28.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | // 21 | // 22 | // Base32 encoding/decoding methods taken from public domain code at 23 | // http://www.cocoadev.com/index.pl?NSDataCategory 24 | 25 | 26 | #import 27 | 28 | 29 | @interface NSData (ELAdditions) 30 | 31 | + (NSData *)el_dataWithBase32String:(NSString *)base32; 32 | - (NSString *)el_base32String; 33 | - (NSData *)el_sha1Digest; 34 | - (NSString *)el_sha1DigestString; 35 | + (NSData *)el_dataWithHexString:(NSString *)hexString; 36 | - (NSString *)el_hexString; 37 | + (NSData *)el_dataWithString:(NSString *)string; 38 | + (NSData *)el_dataWithStringNoNull:(NSString *)string; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Framework/NSData+ELAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+ELAdditions.m 3 | // EllipticLicense 4 | // 5 | // Created by Dmitry Chestnykh on 28.03.09. 6 | // 7 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | // 21 | // 22 | // Base32 encoding/decoding methods taken from public domain code at 23 | // http://www.cocoadev.com/index.pl?NSDataCategory 24 | 25 | 26 | #import "NSData+ELAdditions.h" 27 | #import "openssl/sha.h" 28 | 29 | @implementation NSData (ELAdditions) 30 | 31 | + (NSData *)el_dataWithBase32String:(NSString *)encoded; 32 | { 33 | /* First valid character that can be indexed in decode lookup table */ 34 | static int charDigitsBase = '2'; 35 | 36 | /* Lookup table used to decode() characters in encoded strings */ 37 | static int charDigits[] = 38 | { 26,27,28,29,30,31,-1,-1,-1,-1,-1,-1,-1,-1 // 23456789:;<=>? 39 | ,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14 // @ABCDEFGHIJKLMNO 40 | ,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1 // PQRSTUVWXYZ[\]^_ 41 | ,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14 // `abcdefghijklmno 42 | ,15,16,17,18,19,20,21,22,23,24,25 // pqrstuvwxyz 43 | }; 44 | 45 | if (! [encoded canBeConvertedToEncoding:NSASCIIStringEncoding]) return nil; 46 | const char *chars = [encoded UTF8String]; // avoids using characterAtIndex. 47 | int charsLen = strlen(chars); 48 | 49 | // Note that the code below could detect non canonical Base32 length within the loop. However canonical Base32 length can be tested before entering the loop. 50 | // A canonical Base32 length modulo 8 cannot be: 51 | // 1 (aborts discarding 5 bits at STEP n=0 which produces no byte), 52 | // 3 (aborts discarding 7 bits at STEP n=2 which produces no byte), 53 | // 6 (aborts discarding 6 bits at STEP n=1 which produces no byte). 54 | switch (charsLen & 7) { // test the length of last subblock 55 | case 1: // 5 bits in subblock: 0 useful bits but 5 discarded 56 | case 3: // 15 bits in subblock: 8 useful bits but 7 discarded 57 | case 6: // 30 bits in subblock: 24 useful bits but 6 discarded 58 | return nil; // non-canonical length 59 | } 60 | int charDigitsLen = sizeof(charDigits); 61 | int bytesLen = (charsLen * 5) >> 3; 62 | Byte bytes[bytesLen]; 63 | int bytesOffset = 0, charsOffset = 0; 64 | // Also the code below does test that other discarded bits 65 | // (1 to 4 bits at end) are effectively 0. 66 | while (charsLen > 0) 67 | { 68 | int digit, lastDigit; 69 | // STEP n = 0: Read the 1st Char in a 8-Chars subblock 70 | // Leave 5 bits, asserting there's another encoding Char 71 | if ((digit = (int)chars[charsOffset] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 72 | return nil; // invalid character 73 | lastDigit = digit << 3; 74 | // STEP n = 5: Read the 2nd Char in a 8-Chars subblock 75 | // Insert 3 bits, leave 2 bits, possibly trailing if no more Char 76 | if ((digit = (int)chars[charsOffset + 1] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 77 | return nil; // invalid character 78 | bytes[bytesOffset] = (Byte)((digit >> 2) | lastDigit); 79 | lastDigit = (digit & 3) << 6; 80 | if (charsLen == 2) { 81 | if (lastDigit != 0) return nil; // non-canonical end 82 | break; // discard the 2 trailing null bits 83 | } 84 | // STEP n = 2: Read the 3rd Char in a 8-Chars subblock 85 | // Leave 7 bits, asserting there's another encoding Char 86 | if ((digit = (int)chars[charsOffset + 2] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 87 | return nil; // invalid character 88 | lastDigit |= (Byte)(digit << 1); 89 | // STEP n = 7: Read the 4th Char in a 8-chars Subblock 90 | // Insert 1 bit, leave 4 bits, possibly trailing if no more Char 91 | if ((digit = (int)chars[charsOffset + 3] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 92 | return nil; // invalid character 93 | bytes[bytesOffset + 1] = (Byte)((digit >> 4) | lastDigit); 94 | lastDigit = (Byte)((digit & 15) << 4); 95 | if (charsLen == 4) { 96 | if (lastDigit != 0) return nil; // non-canonical end 97 | break; // discard the 4 trailing null bits 98 | } 99 | // STEP n = 4: Read the 5th Char in a 8-Chars subblock 100 | // Insert 4 bits, leave 1 bit, possibly trailing if no more Char 101 | if ((digit = (int)chars[charsOffset + 4] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 102 | return nil; // invalid character 103 | bytes[bytesOffset + 2] = (Byte)((digit >> 1) | lastDigit); 104 | lastDigit = (Byte)((digit & 1) << 7); 105 | if (charsLen == 5) { 106 | if (lastDigit != 0) return nil; // non-canonical end 107 | break; // discard the 1 trailing null bit 108 | } 109 | // STEP n = 1: Read the 6th Char in a 8-Chars subblock 110 | // Leave 6 bits, asserting there's another encoding Char 111 | if ((digit = (int)chars[charsOffset + 5] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 112 | return nil; // invalid character 113 | lastDigit |= (Byte)(digit << 2); 114 | // STEP n = 6: Read the 7th Char in a 8-Chars subblock 115 | // Insert 2 bits, leave 3 bits, possibly trailing if no more Char 116 | if ((digit = (int)chars[charsOffset + 6] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 117 | return nil; // invalid character 118 | bytes[bytesOffset + 3] = (Byte)((digit >> 3) | lastDigit); 119 | lastDigit = (Byte)((digit & 7) << 5); 120 | if (charsLen == 7) { 121 | if (lastDigit != 0) return nil; // non-canonical end 122 | break; // discard the 3 trailing null bits 123 | } 124 | // STEP n = 3: Read the 8th Char in a 8-Chars subblock 125 | // Insert 5 bits, leave 0 bit, next encoding Char may not exist 126 | if ((digit = (int)chars[charsOffset + 7] - charDigitsBase) < 0 || digit >= charDigitsLen || (digit = charDigits[digit]) == -1) 127 | return nil; // invalid character 128 | bytes[bytesOffset + 4] = (Byte)(digit | lastDigit); 129 | //// This point is always reached for chars.length multiple of 8 130 | charsOffset += 8; 131 | bytesOffset += 5; 132 | charsLen -= 8; 133 | } 134 | // On loop exit, discard the n trailing null bits 135 | return [NSData dataWithBytes:bytes length:sizeof(bytes)]; 136 | } 137 | 138 | - (NSString *)el_base32String; 139 | { 140 | /* Lookup table used to canonically encode() groups of data bits */ 141 | static char canonicalChars[] = 142 | { 'A','B','C','D','E','F','G','H','I','J','K','L','M' // 00..12 143 | ,'N','O','P','Q','R','S','T','U','V','W','X','Y','Z' // 13..25 144 | ,'2','3','4','5','6','7' // 26..31 145 | }; 146 | const Byte *bytes = [self bytes]; 147 | int bytesOffset = 0, bytesLen = [self length]; 148 | int charsOffset = 0, charsLen = ((bytesLen << 3) + 4) / 5; 149 | char chars[charsLen+1]; // +1 for terminating null 150 | while (bytesLen != 0) { 151 | int digit, lastDigit; 152 | // INVARIANTS FOR EACH STEP n in [0..5[; digit in [0..31[; 153 | // The remaining n bits are already aligned on top positions 154 | // of the 5 least bits of digit, the other bits are 0. 155 | ////// STEP n = 0: insert new 5 bits, leave 3 bits 156 | digit = bytes[bytesOffset] & 255; 157 | chars[charsOffset] = canonicalChars[digit >> 3]; 158 | lastDigit = (digit & 7) << 2; 159 | if (bytesLen == 1) { // put the last 3 bits 160 | chars[charsOffset + 1] = canonicalChars[lastDigit]; 161 | break; 162 | } 163 | ////// STEP n = 3: insert 2 new bits, then 5 bits, leave 1 bit 164 | digit = bytes[bytesOffset + 1] & 255; 165 | chars[charsOffset + 1] = canonicalChars[(digit >> 6) | lastDigit]; 166 | chars[charsOffset + 2] = canonicalChars[(digit >> 1) & 31]; 167 | lastDigit = (digit & 1) << 4; 168 | if (bytesLen == 2) { // put the last 1 bit 169 | chars[charsOffset + 3] = canonicalChars[lastDigit]; 170 | break; 171 | } 172 | ////// STEP n = 1: insert 4 new bits, leave 4 bit 173 | digit = bytes[bytesOffset + 2] & 255; 174 | chars[charsOffset + 3] = canonicalChars[(digit >> 4) | lastDigit]; 175 | lastDigit = (digit & 15) << 1; 176 | if (bytesLen == 3) { // put the last 1 bits 177 | chars[charsOffset + 4] = canonicalChars[lastDigit]; 178 | break; 179 | } 180 | ////// STEP n = 4: insert 1 new bit, then 5 bits, leave 2 bits 181 | digit = bytes[bytesOffset + 3] & 255; 182 | chars[charsOffset + 4] = canonicalChars[(digit >> 7) | lastDigit]; 183 | chars[charsOffset + 5] = canonicalChars[(digit >> 2) & 31]; 184 | lastDigit = (digit & 3) << 3; 185 | if (bytesLen == 4) { // put the last 2 bits 186 | chars[charsOffset + 6] = canonicalChars[lastDigit]; 187 | break; 188 | } 189 | ////// STEP n = 2: insert 3 new bits, then 5 bits, leave 0 bit 190 | digit = bytes[bytesOffset + 4] & 255; 191 | chars[charsOffset + 6] = canonicalChars[(digit >> 5) | lastDigit]; 192 | chars[charsOffset + 7] = canonicalChars[digit & 31]; 193 | //// This point is always reached for bytes.length multiple of 5 194 | bytesOffset += 5; 195 | charsOffset += 8; 196 | bytesLen -= 5; 197 | } 198 | //return [NSString stringWithCString:chars length:sizeof(chars)]; // deprecated 199 | chars[charsLen] = '\0'; 200 | return [NSString stringWithCString:chars encoding:NSASCIIStringEncoding]; 201 | } 202 | 203 | - (NSData *)el_sha1Digest; 204 | { 205 | unsigned char digest[SHA_DIGEST_LENGTH]; 206 | SHA1([self bytes], [self length], digest); 207 | return [NSData dataWithBytes:digest length:SHA_DIGEST_LENGTH]; 208 | } 209 | 210 | - (NSString *)el_sha1DigestString; 211 | { 212 | return [[self el_sha1Digest] el_hexString]; 213 | } 214 | 215 | - (NSString *)el_hexString; 216 | { 217 | const unsigned char *bytes = [self bytes]; 218 | NSMutableString *hexString = [[[NSMutableString alloc] initWithCapacity:[self length] * 2] autorelease]; 219 | for (int i = 0; i < [self length]; i++) 220 | [hexString appendFormat:@"%02x", (unsigned char)(bytes[i])]; 221 | return [hexString uppercaseString]; 222 | } 223 | 224 | + (NSData *)el_dataWithHexString:(NSString *)hexString; 225 | { 226 | NSMutableData *data = [NSMutableData dataWithCapacity:[hexString length]/2]; 227 | char *chars = (char *)[hexString UTF8String]; 228 | unsigned char value; 229 | while (*chars != '\0') { 230 | if (*chars >= '0' && *chars <= '9') 231 | value = (*chars - '0') << 4; 232 | else if (*chars >= 'a' && *chars <= 'f') 233 | value = (*chars - 'a' + 10) << 4; 234 | else if (*chars >= 'A' && *chars <= 'F') 235 | value = (*chars - 'A' + 10) << 4; 236 | else 237 | return nil; 238 | 239 | chars++; 240 | if (*chars >= '0' && *chars <= '9') 241 | value |= *chars - '0'; 242 | else if (*chars >= 'a' && *chars <= 'f') 243 | value |= *chars - 'a' + 10; 244 | else if (*chars >= 'A' && *chars <= 'F') 245 | value |= *chars - 'A' + 10; 246 | else 247 | return nil; 248 | [data appendBytes:&value length:sizeof(value)]; 249 | chars++; 250 | } 251 | return data; 252 | } 253 | 254 | + (NSData *)el_dataWithString:(NSString *)string; 255 | { 256 | const char *bytes = [string UTF8String]; 257 | return [NSData dataWithBytes:bytes length:strlen(bytes)]; 258 | } 259 | 260 | + (NSData *)el_dataWithStringNoNull:(NSString *)string; 261 | { 262 | const char *bytes = [string UTF8String]; 263 | size_t lengthWithoutNull = strlen(bytes)-1; 264 | if (lengthWithoutNull <= 0) 265 | return nil; 266 | return [NSData dataWithBytes:bytes length:lengthWithoutNull]; 267 | } 268 | 269 | 270 | @end 271 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | EllipticLicense 2 | =============== 3 | 4 | Short product key generation and validation framework based on elliptic curves digital signatures (ECDSA) for Mac OS X/Cocoa. 5 | 6 | Project goal: replacement for AquaticPrime with shorter keys and similar or better security. 7 | 8 | *Documentation will be available later... For now, read EllipticLicense.h* 9 | 10 | [Watch screencast](http://www.youtube.com/watch?v=lcT8YcbUpg0) 11 | 12 | ## Example keys 13 | 14 | 112-bit curve (~ equivalent to RSA-512, 2^56 bit security): 15 | 16 | Licensed to: John Doe 17 | License key: HQYRV-OZFNZ-M3L7B-WA644-CXLG4-D7IRD-QZ6FY-GJGTO-MEXEG 18 | 19 | 128-bit curve (2^64 bit security): 20 | 21 | Licensed to: John Doe 22 | License key: YBFB-L264-32WL-KHK4-DA4L-L7VW-HGCV-PO3U-PFF6-RJHW-MRBS-5OW4-53WA 23 | 24 | 160-bit curve (~ equivalent to RSA-1024, 2^80 bit security): 25 | 26 | Licensed to: John Doe 27 | License key: IPAA6CH2-2STFJTCW-PYBDDBDM-YK4ZYA6N-3YE624E4-2K7KFDLE-LODJEN5W-WRADC652 28 | 29 | ## EllipticLicenseDeveloper App 30 | 31 | 32 | There's a GUI application for managing your project public and private keys, generating licenses and blocking keys called EllipticLicenseDeveloper included. 33 | 34 | 35 | ## Requirements 36 | 37 | Mac OS X 10.6 (because it includes libcrypto.0.9.8d.dylib, don't forget to link you project with it). 38 | 39 | 40 | License 41 | -------- 42 | 43 | EllipticLicense is licensed under Apache 2 license. See LICENSE. License! 44 | 45 | 46 | Mailing list 47 | ------------ 48 | 49 | Send email to to subscribe. 50 | 51 | * * * 52 | 53 | Made by [Coding Robots](http://www.codingrobots.com) 54 | -------------------------------------------------------------------------------- /Server/PHP/ELConfig.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Server/PHP/ELGenerator.php: -------------------------------------------------------------------------------- 1 | "error reading parameters from stdin", 34 | 2 => "unknown curve", 35 | 3 => "cannot initialize key", 36 | 4 => "cannot decode public key", 37 | 5 => "cannot decode private key", 38 | 6 => "wrong private or public key", 39 | 7 => "cannot generate signature" 40 | ); 41 | 42 | 43 | function add_dashes($s) 44 | { 45 | global $number_chars_in_dash_group; 46 | if ($number_chars_in_dash_group == 0) 47 | return $s; 48 | return implode("-", str_split($s, $number_chars_in_dash_group)); 49 | } 50 | 51 | 52 | $descriptorspec = array( 53 | 0 => array("pipe", "r"), 54 | 1 => array("pipe", "w"), 55 | ); 56 | 57 | $process = proc_open($elgen_path."elgen", $descriptorspec, $pipes); 58 | 59 | if (is_resource($process)) { 60 | ///*debug*/print "$name\n$curve_name\n$public_key\n$private_key"; 61 | fwrite($pipes[0], "$name\n$curve_name\n$public_key\n$private_key"); 62 | fclose($pipes[0]); 63 | 64 | $key = stream_get_contents($pipes[1]); 65 | fclose($pipes[1]); 66 | 67 | $return = proc_close($process); 68 | if ($return != 0) { 69 | if ($output_errors) 70 | print "Error: ${errors[$return]}\n"; 71 | exit($return); 72 | } 73 | } 74 | $out = str_replace("{#name}", $name, $output_format); 75 | $out = str_replace("{#key}", add_dashes($key), $out); 76 | print $out; 77 | 78 | ?> 79 | -------------------------------------------------------------------------------- /Server/elgen/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | LDFLAGS=-lssl 3 | CFLAGS= 4 | 5 | all: 6 | $(CC) $(CFLAGS) $(LDFLAGS) main.c -o elgen 7 | -------------------------------------------------------------------------------- /Server/elgen/elgen.1: -------------------------------------------------------------------------------- 1 | .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. 2 | .\"See Also: 3 | .\"man mdoc.samples for a complete listing of options 4 | .\"man mdoc for the short list of editing options 5 | .\"/usr/share/misc/mdoc.template 6 | .Dd 03.04.09 \" DATE 7 | .Dt elgen 1 \" Program name and manual section number 8 | .Os Darwin 9 | .Sh NAME \" Section Header - required - don't modify 10 | .Nm elgen, 11 | .\" The following lines are read in generating the apropos(man -k) database. Use only key 12 | .\" words here as the database is built based on the words here and in the .ND line. 13 | .Nm Other_name_for_same_program(), 14 | .Nm Yet another name for the same program. 15 | .\" Use .Nm macro to designate other names for the documented program. 16 | .Nd This line parsed for whatis database. 17 | .Sh SYNOPSIS \" Section Header - required - don't modify 18 | .Nm 19 | .Op Fl abcd \" [-abcd] 20 | .Op Fl a Ar path \" [-a path] 21 | .Op Ar file \" [file] 22 | .Op Ar \" [file ...] 23 | .Ar arg0 \" Underlined argument - use .Ar anywhere to underline 24 | arg2 ... \" Arguments 25 | .Sh DESCRIPTION \" Section Header - required - don't modify 26 | Use the .Nm macro to refer to your program throughout the man page like such: 27 | .Nm 28 | Underlining is accomplished with the .Ar macro like this: 29 | .Ar underlined text . 30 | .Pp \" Inserts a space 31 | A list of items with descriptions: 32 | .Bl -tag -width -indent \" Begins a tagged list 33 | .It item a \" Each item preceded by .It macro 34 | Description of item a 35 | .It item b 36 | Description of item b 37 | .El \" Ends the list 38 | .Pp 39 | A list of flags and their descriptions: 40 | .Bl -tag -width -indent \" Differs from above in tag removed 41 | .It Fl a \"-a flag as a list item 42 | Description of -a flag 43 | .It Fl b 44 | Description of -b flag 45 | .El \" Ends the list 46 | .Pp 47 | .\" .Sh ENVIRONMENT \" May not be needed 48 | .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 49 | .\" .It Ev ENV_VAR_1 50 | .\" Description of ENV_VAR_1 51 | .\" .It Ev ENV_VAR_2 52 | .\" Description of ENV_VAR_2 53 | .\" .El 54 | .Sh FILES \" File used or created by the topic of the man page 55 | .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact 56 | .It Pa /usr/share/file_name 57 | FILE_1 description 58 | .It Pa /Users/joeuser/Library/really_long_file_name 59 | FILE_2 description 60 | .El \" Ends the list 61 | .\" .Sh DIAGNOSTICS \" May not be needed 62 | .\" .Bl -diag 63 | .\" .It Diagnostic Tag 64 | .\" Diagnostic informtion here. 65 | .\" .It Diagnostic Tag 66 | .\" Diagnostic informtion here. 67 | .\" .El 68 | .Sh SEE ALSO 69 | .\" List links in ascending order by section, alphabetically within a section. 70 | .\" Please do not reference files that do not exist without filing a bug report 71 | .Xr a 1 , 72 | .Xr b 1 , 73 | .Xr c 1 , 74 | .Xr a 2 , 75 | .Xr b 2 , 76 | .Xr a 3 , 77 | .Xr b 3 78 | .\" .Sh BUGS \" Document known, unremedied bugs 79 | .\" .Sh HISTORY \" Document history if command behaves in a unique manner -------------------------------------------------------------------------------- /Server/elgen/elgen.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A91F0F612A7ADC500909BFE /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A91F0F512A7ADC500909BFE /* libcrypto.dylib */; }; 11 | 8DD76FAC0486AB0100D96B5E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; }; 12 | 8DD76FB00486AB0100D96B5E /* elgen.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6A0FF2C0290799A04C91782 /* elgen.1 */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 8; 19 | dstPath = /usr/share/man/man1/; 20 | dstSubfolderSpec = 0; 21 | files = ( 22 | 8DD76FB00486AB0100D96B5E /* elgen.1 in CopyFiles */, 23 | ); 24 | runOnlyForDeploymentPostprocessing = 1; 25 | }; 26 | /* End PBXCopyFilesBuildPhase section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 08FB7796FE84155DC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 30 | 0A91F0F512A7ADC500909BFE /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; 31 | 8DD76FB20486AB0100D96B5E /* elgen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = elgen; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | C6A0FF2C0290799A04C91782 /* elgen.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = elgen.1; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | 0A91F0F612A7ADC500909BFE /* libcrypto.dylib in Frameworks */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | 08FB7794FE84155DC02AAC07 /* elgen */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | 08FB7795FE84155DC02AAC07 /* Source */, 51 | C6A0FF2B0290797F04C91782 /* Documentation */, 52 | 1AB674ADFE9D54B511CA2CBB /* Products */, 53 | 0A91F0F512A7ADC500909BFE /* libcrypto.dylib */, 54 | ); 55 | name = elgen; 56 | sourceTree = ""; 57 | }; 58 | 08FB7795FE84155DC02AAC07 /* Source */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 08FB7796FE84155DC02AAC07 /* main.c */, 62 | ); 63 | name = Source; 64 | sourceTree = ""; 65 | }; 66 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 8DD76FB20486AB0100D96B5E /* elgen */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | C6A0FF2B0290797F04C91782 /* Documentation */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | C6A0FF2C0290799A04C91782 /* elgen.1 */, 78 | ); 79 | name = Documentation; 80 | sourceTree = ""; 81 | }; 82 | /* End PBXGroup section */ 83 | 84 | /* Begin PBXNativeTarget section */ 85 | 8DD76FA90486AB0100D96B5E /* elgen */ = { 86 | isa = PBXNativeTarget; 87 | buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "elgen" */; 88 | buildPhases = ( 89 | 8DD76FAB0486AB0100D96B5E /* Sources */, 90 | 8DD76FAD0486AB0100D96B5E /* Frameworks */, 91 | 8DD76FAF0486AB0100D96B5E /* CopyFiles */, 92 | ); 93 | buildRules = ( 94 | ); 95 | dependencies = ( 96 | ); 97 | name = elgen; 98 | productInstallPath = "$(HOME)/bin"; 99 | productName = elgen; 100 | productReference = 8DD76FB20486AB0100D96B5E /* elgen */; 101 | productType = "com.apple.product-type.tool"; 102 | }; 103 | /* End PBXNativeTarget section */ 104 | 105 | /* Begin PBXProject section */ 106 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 107 | isa = PBXProject; 108 | buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "elgen" */; 109 | compatibilityVersion = "Xcode 3.1"; 110 | developmentRegion = English; 111 | hasScannedForEncodings = 1; 112 | knownRegions = ( 113 | English, 114 | Japanese, 115 | French, 116 | German, 117 | ); 118 | mainGroup = 08FB7794FE84155DC02AAC07 /* elgen */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | 8DD76FA90486AB0100D96B5E /* elgen */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXSourcesBuildPhase section */ 128 | 8DD76FAB0486AB0100D96B5E /* Sources */ = { 129 | isa = PBXSourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | 8DD76FAC0486AB0100D96B5E /* main.c in Sources */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXSourcesBuildPhase section */ 137 | 138 | /* Begin XCBuildConfiguration section */ 139 | 1DEB928608733DD80010E9CD /* Debug */ = { 140 | isa = XCBuildConfiguration; 141 | buildSettings = { 142 | ALWAYS_SEARCH_USER_PATHS = NO; 143 | COPY_PHASE_STRIP = NO; 144 | GCC_DYNAMIC_NO_PIC = NO; 145 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 146 | GCC_MODEL_TUNING = G5; 147 | GCC_OPTIMIZATION_LEVEL = 0; 148 | INSTALL_PATH = /usr/local/bin; 149 | LIBRARY_SEARCH_PATHS = ( 150 | "$(inherited)", 151 | "\"$(SRCROOT)/../../lib\"", 152 | ); 153 | PRODUCT_NAME = elgen; 154 | }; 155 | name = Debug; 156 | }; 157 | 1DEB928708733DD80010E9CD /* Release */ = { 158 | isa = XCBuildConfiguration; 159 | buildSettings = { 160 | ALWAYS_SEARCH_USER_PATHS = NO; 161 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 162 | GCC_MODEL_TUNING = G5; 163 | INSTALL_PATH = /usr/local/bin; 164 | LIBRARY_SEARCH_PATHS = ( 165 | "$(inherited)", 166 | "\"$(SRCROOT)/../../lib\"", 167 | ); 168 | PRODUCT_NAME = elgen; 169 | }; 170 | name = Release; 171 | }; 172 | 1DEB928A08733DD80010E9CD /* Debug */ = { 173 | isa = XCBuildConfiguration; 174 | buildSettings = { 175 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 176 | GCC_C_LANGUAGE_STANDARD = c99; 177 | GCC_OPTIMIZATION_LEVEL = 0; 178 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 179 | GCC_WARN_UNUSED_VARIABLE = YES; 180 | HEADER_SEARCH_PATHS = "../../openssl/include//**"; 181 | ONLY_ACTIVE_ARCH = YES; 182 | OTHER_LDFLAGS = ""; 183 | PREBINDING = NO; 184 | SDKROOT = macosx10.6; 185 | SYMROOT = ../../Builds; 186 | }; 187 | name = Debug; 188 | }; 189 | 1DEB928B08733DD80010E9CD /* Release */ = { 190 | isa = XCBuildConfiguration; 191 | buildSettings = { 192 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 193 | GCC_C_LANGUAGE_STANDARD = c99; 194 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 195 | GCC_WARN_UNUSED_VARIABLE = YES; 196 | HEADER_SEARCH_PATHS = "../../openssl/include//**"; 197 | PREBINDING = NO; 198 | SDKROOT = macosx10.6; 199 | SYMROOT = ../../Builds; 200 | }; 201 | name = Release; 202 | }; 203 | /* End XCBuildConfiguration section */ 204 | 205 | /* Begin XCConfigurationList section */ 206 | 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "elgen" */ = { 207 | isa = XCConfigurationList; 208 | buildConfigurations = ( 209 | 1DEB928608733DD80010E9CD /* Debug */, 210 | 1DEB928708733DD80010E9CD /* Release */, 211 | ); 212 | defaultConfigurationIsVisible = 0; 213 | defaultConfigurationName = Release; 214 | }; 215 | 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "elgen" */ = { 216 | isa = XCConfigurationList; 217 | buildConfigurations = ( 218 | 1DEB928A08733DD80010E9CD /* Debug */, 219 | 1DEB928B08733DD80010E9CD /* Release */, 220 | ); 221 | defaultConfigurationIsVisible = 0; 222 | defaultConfigurationName = Release; 223 | }; 224 | /* End XCConfigurationList section */ 225 | }; 226 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 227 | } 228 | -------------------------------------------------------------------------------- /Server/elgen/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // elgen - command line utility for key generation 3 | // Part of EllipticLicense project 4 | // 5 | // Tested on Mac OS X and Linux (x86 and x86_64) 6 | // Make sure to link against libcrypto 0.9.8 or later 7 | // 8 | // Copyright (c) 2009 Dmitry Chestnykh, Coding Robots 9 | // 10 | // Licensed under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | // 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // Error codes 33 | enum { 34 | ERR_STDIN_READ = 1, 35 | ERR_CURVE_UNKNOWN = 2, 36 | ERR_INIT_KEY = 3, 37 | ERR_PUBLIC_KEY_DECODING = 4, 38 | ERR_PRIVATE_KEY_DECODING = 5, 39 | ERR_WRONG_KEYS = 6, 40 | ERR_SIGNING = 7, 41 | }; 42 | 43 | size_t hex2bin(unsigned char **bin, const char *hex) 44 | { 45 | BIGNUM *bn = NULL; 46 | if (!BN_hex2bn(&bn, hex)) 47 | return 0; 48 | size_t buf_len = (size_t)BN_num_bytes(bn); 49 | *bin = OPENSSL_malloc(buf_len); 50 | int len = BN_bn2bin(bn, *bin); 51 | BN_free(bn); 52 | return len; 53 | } 54 | 55 | static const char base32_alphabet[32] = { 56 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 57 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 58 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 59 | 'Y', 'Z', '2', '3', '4', '5', '6', '7' 60 | }; 61 | 62 | size_t base32_encode(char *dst, size_t size, const void *data, size_t len) 63 | { 64 | size_t i = 0; 65 | const uint8_t *p = (const uint8_t*)data; 66 | const char *end = &dst[size]; 67 | char *q = dst; 68 | 69 | do { 70 | size_t j, k; 71 | uint8_t x[5]; 72 | char s[8]; 73 | 74 | switch (len - i) { 75 | case 4: k = 7; break; 76 | case 3: k = 5; break; 77 | case 2: k = 3; break; 78 | case 1: k = 2; break; 79 | default: 80 | k = 8; 81 | } 82 | 83 | for (j = 0; j < 5; j++) 84 | x[j] = i < len ? p[i++] : 0; 85 | 86 | s[0] = (x[0] >> 3); 87 | s[1] = ((x[0] & 0x07) << 2) | (x[1] >> 6); 88 | s[2] = (x[1] >> 1) & 0x1f; 89 | s[3] = ((x[1] & 0x01) << 4) | (x[2] >> 4); 90 | s[4] = ((x[2] & 0x0f) << 1) | (x[3] >> 7); 91 | s[5] = (x[3] >> 2) & 0x1f; 92 | s[6] = ((x[3] & 0x03) << 3) | (x[4] >> 5); 93 | s[7] = x[4] & 0x1f; 94 | 95 | for (j = 0; j < k && q != end; j++) 96 | *q++ = base32_alphabet[(uint8_t) s[j]]; 97 | 98 | } while (i < len); 99 | return q - dst; 100 | } 101 | 102 | 103 | int read_params(char *name, size_t name_size, char *curve_name, size_t curve_size, char *pubkey, size_t pubkey_size, char *privkey, size_t privkey_size) 104 | { 105 | // Read "name\ncurve_name\npubkey\nprivkey\n from stdin 106 | if (fgets(name, name_size, stdin) == NULL || 107 | fgets(curve_name, curve_size, stdin) == NULL || 108 | fgets(pubkey, pubkey_size, stdin) == NULL || 109 | (fgets(privkey, privkey_size, stdin) == NULL && !feof(stdin))) 110 | return 0; 111 | // Get rid of \n 112 | size_t len; 113 | if ((len = strlen(name)) > 1) 114 | name[len-1] = '\0'; 115 | if ((len = strlen(curve_name)) > 1) 116 | curve_name[len-1] = '\0'; 117 | if ((len = strlen(pubkey)) > 1) 118 | pubkey[len-1] = '\0'; 119 | if ((len = strlen(privkey)) > 1 && privkey[len] == '\n') 120 | privkey[len-1] = '\0'; 121 | return 1; 122 | } 123 | 124 | int main (int argc, const char * argv[]) { 125 | 126 | EC_KEY *eckey; 127 | 128 | unsigned int curve; 129 | size_t digest_len; 130 | 131 | char name[1024], curve_name[200], pubkey[1024], privkey[1024]; 132 | 133 | if (!read_params(name, 1024, curve_name, 200, pubkey, 1024, privkey, 1024)) 134 | return ERR_STDIN_READ; 135 | 136 | ///*debug*/printf("%s\n%s\n%s\n%s\n", name, curve_name, pubkey, privkey); 137 | 138 | // Get curve type and digest_len 139 | if (strcmp(curve_name, "secp112r1") == 0) { 140 | curve = NID_secp112r1; 141 | digest_len = 14; 142 | } else if (strcmp(curve_name, "secp128r1") == 0) { 143 | curve = NID_secp128r1; 144 | digest_len = 16; 145 | } else if (strcmp(curve_name, "secp160r1") == 0) { 146 | curve = NID_secp160r1; 147 | digest_len = 20; 148 | } else { 149 | return ERR_CURVE_UNKNOWN; 150 | } 151 | 152 | eckey = EC_KEY_new_by_curve_name(NID_secp112r1); 153 | if (eckey == NULL) 154 | return ERR_INIT_KEY; 155 | 156 | // set public key 157 | unsigned char *bin = NULL; 158 | size_t len = hex2bin(&bin, pubkey); 159 | if (len == 0) 160 | return ERR_PUBLIC_KEY_DECODING; 161 | const unsigned char *bin_copy = bin; 162 | eckey = o2i_ECPublicKey(&eckey, &bin_copy, len); 163 | OPENSSL_free(bin); 164 | 165 | // set private key 166 | len = hex2bin(&bin, privkey); 167 | if (len == 0) 168 | return ERR_PUBLIC_KEY_DECODING; 169 | bin_copy = bin; 170 | eckey = d2i_ECPrivateKey(&eckey, &bin_copy, len); 171 | OPENSSL_free(bin); 172 | 173 | // check keys 174 | if (!EC_KEY_check_key(eckey)) 175 | return ERR_WRONG_KEYS; 176 | 177 | // calculate sha-1 178 | unsigned char digest[SHA_DIGEST_LENGTH]; 179 | SHA1((unsigned char *)name, strlen(name)-1, digest); 180 | 181 | // sign 182 | ECDSA_SIG *sig = ECDSA_do_sign(digest, digest_len, eckey); 183 | if (sig == NULL) 184 | return ERR_SIGNING; 185 | 186 | size_t rlen = BN_num_bytes(sig->r); 187 | size_t slen = BN_num_bytes(sig->s); 188 | size_t binlen = rlen + slen; 189 | bin = OPENSSL_malloc(binlen); 190 | bzero(bin, binlen); 191 | BN_bn2bin(sig->r, bin); 192 | BN_bn2bin(sig->s, bin + rlen); // join two values into bin 193 | ECDSA_SIG_free(sig); 194 | 195 | size_t b32len = binlen * 8 / 5 + 2; 196 | char *base32 = OPENSSL_malloc(b32len); 197 | bzero(base32, b32len); 198 | 199 | base32_encode(base32, b32len, bin, binlen); 200 | printf("%s", base32); 201 | 202 | OPENSSL_free(bin); 203 | OPENSSL_free(base32); 204 | return 0; 205 | } 206 | -------------------------------------------------------------------------------- /Static Library/EllipticLicense.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/Static Library/EllipticLicense.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /Static Library/EllipticLicense.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A76B9C5106FE06A0048097B /* libcrypto.0.9.8.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A76B9C4106FE06A0048097B /* libcrypto.0.9.8.dylib */; }; 11 | 0A8564600F82C26600AEAB7A /* NSData+ELAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A85645C0F82C26600AEAB7A /* NSData+ELAdditions.h */; }; 12 | 0A8564610F82C26600AEAB7A /* NSData+ELAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A85645D0F82C26600AEAB7A /* NSData+ELAdditions.m */; }; 13 | 0A8564620F82C26600AEAB7A /* EllipticLicense.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A85645E0F82C26600AEAB7A /* EllipticLicense.h */; }; 14 | 0A8564630F82C26600AEAB7A /* EllipticLicense.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A85645F0F82C26600AEAB7A /* EllipticLicense.m */; }; 15 | D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 20 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 21 | 0A76B9C4106FE06A0048097B /* libcrypto.0.9.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.0.9.8.dylib; path = /usr/lib/libcrypto.0.9.8.dylib; sourceTree = ""; }; 22 | 0A85645C0F82C26600AEAB7A /* NSData+ELAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSData+ELAdditions.h"; path = "../Framework/NSData+ELAdditions.h"; sourceTree = SOURCE_ROOT; }; 23 | 0A85645D0F82C26600AEAB7A /* NSData+ELAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+ELAdditions.m"; path = "../Framework/NSData+ELAdditions.m"; sourceTree = SOURCE_ROOT; }; 24 | 0A85645E0F82C26600AEAB7A /* EllipticLicense.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EllipticLicense.h; path = ../Framework/EllipticLicense.h; sourceTree = SOURCE_ROOT; }; 25 | 0A85645F0F82C26600AEAB7A /* EllipticLicense.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EllipticLicense.m; path = ../Framework/EllipticLicense.m; sourceTree = SOURCE_ROOT; }; 26 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 27 | 32DBCF5E0370ADEE00C91783 /* EllipticLicense_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EllipticLicense_Prefix.pch; sourceTree = ""; }; 28 | D2AAC07E0554694100DB518D /* libEllipticLicense.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libEllipticLicense.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | D2F7E8BE07B2D77200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | D2AAC07C0554694100DB518D /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */, 38 | 0A76B9C5106FE06A0048097B /* libcrypto.0.9.8.dylib in Frameworks */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | 034768DFFF38A50411DB9C8B /* Products */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | D2AAC07E0554694100DB518D /* libEllipticLicense.a */, 49 | ); 50 | name = Products; 51 | sourceTree = ""; 52 | }; 53 | 0867D691FE84028FC02AAC07 /* EllipticLicense */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 08FB77AEFE84172EC02AAC07 /* Classes */, 57 | 32C88DFF0371C24200C91783 /* Other Sources */, 58 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 59 | 034768DFFF38A50411DB9C8B /* Products */, 60 | ); 61 | name = EllipticLicense; 62 | sourceTree = ""; 63 | }; 64 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 68 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 69 | ); 70 | name = "External Frameworks and Libraries"; 71 | sourceTree = ""; 72 | }; 73 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 0A85645C0F82C26600AEAB7A /* NSData+ELAdditions.h */, 77 | 0A85645D0F82C26600AEAB7A /* NSData+ELAdditions.m */, 78 | 0A85645E0F82C26600AEAB7A /* EllipticLicense.h */, 79 | 0A85645F0F82C26600AEAB7A /* EllipticLicense.m */, 80 | ); 81 | name = Classes; 82 | sourceTree = ""; 83 | }; 84 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 0A76B9C4106FE06A0048097B /* libcrypto.0.9.8.dylib */, 88 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 89 | ); 90 | name = "Linked Frameworks"; 91 | sourceTree = ""; 92 | }; 93 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 97 | D2F7E8BE07B2D77200F64583 /* CoreData.framework */, 98 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 99 | ); 100 | name = "Other Frameworks"; 101 | sourceTree = ""; 102 | }; 103 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 32DBCF5E0370ADEE00C91783 /* EllipticLicense_Prefix.pch */, 107 | ); 108 | name = "Other Sources"; 109 | sourceTree = ""; 110 | }; 111 | /* End PBXGroup section */ 112 | 113 | /* Begin PBXHeadersBuildPhase section */ 114 | D2AAC07A0554694100DB518D /* Headers */ = { 115 | isa = PBXHeadersBuildPhase; 116 | buildActionMask = 2147483647; 117 | files = ( 118 | 0A8564600F82C26600AEAB7A /* NSData+ELAdditions.h in Headers */, 119 | 0A8564620F82C26600AEAB7A /* EllipticLicense.h in Headers */, 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | /* End PBXHeadersBuildPhase section */ 124 | 125 | /* Begin PBXNativeTarget section */ 126 | D2AAC07D0554694100DB518D /* EllipticLicense */ = { 127 | isa = PBXNativeTarget; 128 | buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "EllipticLicense" */; 129 | buildPhases = ( 130 | D2AAC07A0554694100DB518D /* Headers */, 131 | D2AAC07B0554694100DB518D /* Sources */, 132 | D2AAC07C0554694100DB518D /* Frameworks */, 133 | ); 134 | buildRules = ( 135 | ); 136 | dependencies = ( 137 | ); 138 | name = EllipticLicense; 139 | productName = EllipticLicense; 140 | productReference = D2AAC07E0554694100DB518D /* libEllipticLicense.a */; 141 | productType = "com.apple.product-type.library.static"; 142 | }; 143 | /* End PBXNativeTarget section */ 144 | 145 | /* Begin PBXProject section */ 146 | 0867D690FE84028FC02AAC07 /* Project object */ = { 147 | isa = PBXProject; 148 | buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "EllipticLicense" */; 149 | compatibilityVersion = "Xcode 3.1"; 150 | developmentRegion = English; 151 | hasScannedForEncodings = 1; 152 | knownRegions = ( 153 | English, 154 | Japanese, 155 | French, 156 | German, 157 | ); 158 | mainGroup = 0867D691FE84028FC02AAC07 /* EllipticLicense */; 159 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 160 | projectDirPath = ""; 161 | projectRoot = ""; 162 | targets = ( 163 | D2AAC07D0554694100DB518D /* EllipticLicense */, 164 | ); 165 | }; 166 | /* End PBXProject section */ 167 | 168 | /* Begin PBXSourcesBuildPhase section */ 169 | D2AAC07B0554694100DB518D /* Sources */ = { 170 | isa = PBXSourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 0A8564610F82C26600AEAB7A /* NSData+ELAdditions.m in Sources */, 174 | 0A8564630F82C26600AEAB7A /* EllipticLicense.m in Sources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXSourcesBuildPhase section */ 179 | 180 | /* Begin XCBuildConfiguration section */ 181 | 1DEB921F08733DC00010E9CD /* Debug */ = { 182 | isa = XCBuildConfiguration; 183 | buildSettings = { 184 | ALWAYS_SEARCH_USER_PATHS = NO; 185 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 186 | COPY_PHASE_STRIP = NO; 187 | GCC_DYNAMIC_NO_PIC = NO; 188 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 189 | GCC_MODEL_TUNING = G5; 190 | GCC_OPTIMIZATION_LEVEL = 0; 191 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 192 | GCC_PREFIX_HEADER = EllipticLicense_Prefix.pch; 193 | INSTALL_PATH = /usr/local/lib; 194 | LIBRARY_SEARCH_PATHS = ( 195 | "$(inherited)", 196 | "\"$(SRCROOT)/../../lib\"", 197 | "\"$(SRCROOT)/../lib\"", 198 | ); 199 | ONLY_ACTIVE_ARCH = YES; 200 | PRODUCT_NAME = EllipticLicense; 201 | }; 202 | name = Debug; 203 | }; 204 | 1DEB922008733DC00010E9CD /* Release */ = { 205 | isa = XCBuildConfiguration; 206 | buildSettings = { 207 | ALWAYS_SEARCH_USER_PATHS = NO; 208 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 209 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 210 | GCC_MODEL_TUNING = G5; 211 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 212 | GCC_PREFIX_HEADER = EllipticLicense_Prefix.pch; 213 | INSTALL_PATH = /usr/local/lib; 214 | LIBRARY_SEARCH_PATHS = ( 215 | "$(inherited)", 216 | "\"$(SRCROOT)/../../lib\"", 217 | "\"$(SRCROOT)/../lib\"", 218 | ); 219 | PRODUCT_NAME = EllipticLicense; 220 | }; 221 | name = Release; 222 | }; 223 | 1DEB922308733DC00010E9CD /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 227 | GCC_C_LANGUAGE_STANDARD = c99; 228 | GCC_ENABLE_OBJC_GC = supported; 229 | GCC_OPTIMIZATION_LEVEL = 0; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 231 | GCC_WARN_UNUSED_VARIABLE = YES; 232 | HEADER_SEARCH_PATHS = "../openssl/include/**"; 233 | ONLY_ACTIVE_ARCH = YES; 234 | OTHER_LDFLAGS = "-ObjC"; 235 | PREBINDING = NO; 236 | SDKROOT = macosx10.6; 237 | SYMROOT = ../Builds; 238 | }; 239 | name = Debug; 240 | }; 241 | 1DEB922408733DC00010E9CD /* Release */ = { 242 | isa = XCBuildConfiguration; 243 | buildSettings = { 244 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 245 | GCC_C_LANGUAGE_STANDARD = c99; 246 | GCC_ENABLE_OBJC_GC = supported; 247 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 248 | GCC_WARN_UNUSED_VARIABLE = YES; 249 | HEADER_SEARCH_PATHS = "../openssl/include/**"; 250 | OTHER_LDFLAGS = "-ObjC"; 251 | PREBINDING = NO; 252 | SDKROOT = macosx10.6; 253 | SYMROOT = ../Builds; 254 | }; 255 | name = Release; 256 | }; 257 | /* End XCBuildConfiguration section */ 258 | 259 | /* Begin XCConfigurationList section */ 260 | 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "EllipticLicense" */ = { 261 | isa = XCConfigurationList; 262 | buildConfigurations = ( 263 | 1DEB921F08733DC00010E9CD /* Debug */, 264 | 1DEB922008733DC00010E9CD /* Release */, 265 | ); 266 | defaultConfigurationIsVisible = 0; 267 | defaultConfigurationName = Release; 268 | }; 269 | 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "EllipticLicense" */ = { 270 | isa = XCConfigurationList; 271 | buildConfigurations = ( 272 | 1DEB922308733DC00010E9CD /* Debug */, 273 | 1DEB922408733DC00010E9CD /* Release */, 274 | ); 275 | defaultConfigurationIsVisible = 0; 276 | defaultConfigurationName = Release; 277 | }; 278 | /* End XCConfigurationList section */ 279 | }; 280 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 281 | } 282 | -------------------------------------------------------------------------------- /Static Library/EllipticLicense_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'EllipticLicenseStaticLibrary' target in the 'EllipticLicenseStaticLibrary' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Static Library/README: -------------------------------------------------------------------------------- 1 | EllipticLicense Static library. 2 | Output: libEllipticLicense.a 3 | 4 | NOTE: To use it, after adding libEllipticLicense.a to your project, add -ObjC to Linker Flags in your target/project properties. 5 | 6 | NOTE about 10.6: 10.6 SDK broke -ObjC, so use -all_load in Linker Flags. 7 | 8 | It uses the same source code as framework (../Framework/) -------------------------------------------------------------------------------- /Test/Test.1: -------------------------------------------------------------------------------- 1 | .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. 2 | .\"See Also: 3 | .\"man mdoc.samples for a complete listing of options 4 | .\"man mdoc for the short list of editing options 5 | .\"/usr/share/misc/mdoc.template 6 | .Dd 27.03.09 \" DATE 7 | .Dt Test 1 \" Program name and manual section number 8 | .Os Darwin 9 | .Sh NAME \" Section Header - required - don't modify 10 | .Nm Test, 11 | .\" The following lines are read in generating the apropos(man -k) database. Use only key 12 | .\" words here as the database is built based on the words here and in the .ND line. 13 | .Nm Other_name_for_same_program(), 14 | .Nm Yet another name for the same program. 15 | .\" Use .Nm macro to designate other names for the documented program. 16 | .Nd This line parsed for whatis database. 17 | .Sh SYNOPSIS \" Section Header - required - don't modify 18 | .Nm 19 | .Op Fl abcd \" [-abcd] 20 | .Op Fl a Ar path \" [-a path] 21 | .Op Ar file \" [file] 22 | .Op Ar \" [file ...] 23 | .Ar arg0 \" Underlined argument - use .Ar anywhere to underline 24 | arg2 ... \" Arguments 25 | .Sh DESCRIPTION \" Section Header - required - don't modify 26 | Use the .Nm macro to refer to your program throughout the man page like such: 27 | .Nm 28 | Underlining is accomplished with the .Ar macro like this: 29 | .Ar underlined text . 30 | .Pp \" Inserts a space 31 | A list of items with descriptions: 32 | .Bl -tag -width -indent \" Begins a tagged list 33 | .It item a \" Each item preceded by .It macro 34 | Description of item a 35 | .It item b 36 | Description of item b 37 | .El \" Ends the list 38 | .Pp 39 | A list of flags and their descriptions: 40 | .Bl -tag -width -indent \" Differs from above in tag removed 41 | .It Fl a \"-a flag as a list item 42 | Description of -a flag 43 | .It Fl b 44 | Description of -b flag 45 | .El \" Ends the list 46 | .Pp 47 | .\" .Sh ENVIRONMENT \" May not be needed 48 | .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 49 | .\" .It Ev ENV_VAR_1 50 | .\" Description of ENV_VAR_1 51 | .\" .It Ev ENV_VAR_2 52 | .\" Description of ENV_VAR_2 53 | .\" .El 54 | .Sh FILES \" File used or created by the topic of the man page 55 | .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact 56 | .It Pa /usr/share/file_name 57 | FILE_1 description 58 | .It Pa /Users/joeuser/Library/really_long_file_name 59 | FILE_2 description 60 | .El \" Ends the list 61 | .\" .Sh DIAGNOSTICS \" May not be needed 62 | .\" .Bl -diag 63 | .\" .It Diagnostic Tag 64 | .\" Diagnostic informtion here. 65 | .\" .It Diagnostic Tag 66 | .\" Diagnostic informtion here. 67 | .\" .El 68 | .Sh SEE ALSO 69 | .\" List links in ascending order by section, alphabetically within a section. 70 | .\" Please do not reference files that do not exist without filing a bug report 71 | .Xr a 1 , 72 | .Xr b 1 , 73 | .Xr c 1 , 74 | .Xr a 2 , 75 | .Xr b 2 , 76 | .Xr a 3 , 77 | .Xr b 3 78 | .\" .Sh BUGS \" Document known, unremedied bugs 79 | .\" .Sh HISTORY \" Document history if command behaves in a unique manner -------------------------------------------------------------------------------- /Test/Test.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "EllipticLicense.h" 3 | 4 | int main (int argc, const char * argv[]) { 5 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 6 | 7 | // insert code here... 8 | NSLog(@"Hello, World!"); 9 | 10 | 11 | // NSString *publicKey = @"048049FABC0721B04AA24A1146D72286D120D7278604E8891ED3BF6DE8"; 12 | // NSString *privateKey = @"3081C6020101040E0392C3CA6FC55D0BD0A163E2907EA0818E30818B020101301A06072A8648CE3D0101020F00DB7C2ABF62E35E668076BEAD208B3037040EDB7C2ABF62E35E668076BEAD2088040E659EF8BA043916EEDE8911702B2203150000F50B028E4D696E676875615175290472783FB1041D0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500020F00DB7C2ABF62E35E7628DFAC6561C5020101A120031E00048049FABC0721B04AA24A1146D72286D120D7278604E8891ED3BF6DE8"; 13 | //EllipticLicense *el = [[EllipticLicense alloc] initWithPublicKey:publicKey privateKey:privateKey]; 14 | //[el logKeys]; 15 | 16 | EllipticLicense *el = [[EllipticLicense alloc] init]; 17 | [el setCurveName:ELCurveNameSecp160r1]; 18 | if (![el generateKeys]) 19 | NSLog(@"not generated"); 20 | [el logKeys]; 21 | 22 | NSString *licenseKey = [el licenseKeyForName:@"Test name"]; 23 | NSLog(@"\nLicense (%d): %@", [licenseKey length], licenseKey); 24 | NSString *p = [el publicKey]; 25 | [el release]; 26 | 27 | el = [[EllipticLicense alloc] initWithPublicKey:p curveName:ELCurveNameSecp160r1]; 28 | //licenseKey = [licenseKey stringByAppendingString:@"BABBA"]; 29 | if ([el verifyLicenseKey:licenseKey forName:@"Test name"]) 30 | NSLog(@"License VALID."); 31 | else 32 | NSLog(@"License invalid!"); 33 | [el release]; 34 | 35 | [pool drain]; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Test/Test.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/ellipticlicense/72c3f747d656d20cf2b7c32f126484420460a3cf/Test/Test.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /Test/Test.xcodeproj/dmitry.mode1v3: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ActivePerspectiveName 6 | Project 7 | AllowedModules 8 | 9 | 10 | BundleLoadPath 11 | 12 | MaxInstances 13 | n 14 | Module 15 | PBXSmartGroupTreeModule 16 | Name 17 | Groups and Files Outline View 18 | 19 | 20 | BundleLoadPath 21 | 22 | MaxInstances 23 | n 24 | Module 25 | PBXNavigatorGroup 26 | Name 27 | Editor 28 | 29 | 30 | BundleLoadPath 31 | 32 | MaxInstances 33 | n 34 | Module 35 | XCTaskListModule 36 | Name 37 | Task List 38 | 39 | 40 | BundleLoadPath 41 | 42 | MaxInstances 43 | n 44 | Module 45 | XCDetailModule 46 | Name 47 | File and Smart Group Detail Viewer 48 | 49 | 50 | BundleLoadPath 51 | 52 | MaxInstances 53 | 1 54 | Module 55 | PBXBuildResultsModule 56 | Name 57 | Detailed Build Results Viewer 58 | 59 | 60 | BundleLoadPath 61 | 62 | MaxInstances 63 | 1 64 | Module 65 | PBXProjectFindModule 66 | Name 67 | Project Batch Find Tool 68 | 69 | 70 | BundleLoadPath 71 | 72 | MaxInstances 73 | n 74 | Module 75 | XCProjectFormatConflictsModule 76 | Name 77 | Project Format Conflicts List 78 | 79 | 80 | BundleLoadPath 81 | 82 | MaxInstances 83 | n 84 | Module 85 | PBXBookmarksModule 86 | Name 87 | Bookmarks Tool 88 | 89 | 90 | BundleLoadPath 91 | 92 | MaxInstances 93 | n 94 | Module 95 | PBXClassBrowserModule 96 | Name 97 | Class Browser 98 | 99 | 100 | BundleLoadPath 101 | 102 | MaxInstances 103 | n 104 | Module 105 | PBXCVSModule 106 | Name 107 | Source Code Control Tool 108 | 109 | 110 | BundleLoadPath 111 | 112 | MaxInstances 113 | n 114 | Module 115 | PBXDebugBreakpointsModule 116 | Name 117 | Debug Breakpoints Tool 118 | 119 | 120 | BundleLoadPath 121 | 122 | MaxInstances 123 | n 124 | Module 125 | XCDockableInspector 126 | Name 127 | Inspector 128 | 129 | 130 | BundleLoadPath 131 | 132 | MaxInstances 133 | n 134 | Module 135 | PBXOpenQuicklyModule 136 | Name 137 | Open Quickly Tool 138 | 139 | 140 | BundleLoadPath 141 | 142 | MaxInstances 143 | 1 144 | Module 145 | PBXDebugSessionModule 146 | Name 147 | Debugger 148 | 149 | 150 | BundleLoadPath 151 | 152 | MaxInstances 153 | 1 154 | Module 155 | PBXDebugCLIModule 156 | Name 157 | Debug Console 158 | 159 | 160 | BundleLoadPath 161 | 162 | MaxInstances 163 | n 164 | Module 165 | XCSnapshotModule 166 | Name 167 | Snapshots Tool 168 | 169 | 170 | BundlePath 171 | /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources 172 | Description 173 | DefaultDescriptionKey 174 | DockingSystemVisible 175 | 176 | Extension 177 | mode1v3 178 | FavBarConfig 179 | 180 | PBXProjectModuleGUID 181 | 0A3677800F7D2A1800B4662A 182 | XCBarModuleItemNames 183 | 184 | XCBarModuleItems 185 | 186 | 187 | FirstTimeWindowDisplayed 188 | 189 | Identifier 190 | com.apple.perspectives.project.mode1v3 191 | MajorVersion 192 | 33 193 | MinorVersion 194 | 0 195 | Name 196 | Default 197 | Notifications 198 | 199 | OpenEditors 200 | 201 | PerspectiveWidths 202 | 203 | -1 204 | -1 205 | 206 | Perspectives 207 | 208 | 209 | ChosenToolbarItems 210 | 211 | active-target-popup 212 | active-buildstyle-popup 213 | action 214 | NSToolbarFlexibleSpaceItem 215 | buildOrClean 216 | build-and-goOrGo 217 | com.apple.ide.PBXToolbarStopButton 218 | get-info 219 | toggle-editor 220 | NSToolbarFlexibleSpaceItem 221 | com.apple.pbx.toolbar.searchfield 222 | 223 | ControllerClassBaseName 224 | 225 | IconName 226 | WindowOfProjectWithEditor 227 | Identifier 228 | perspective.project 229 | IsVertical 230 | 231 | Layout 232 | 233 | 234 | ContentConfiguration 235 | 236 | PBXBottomSmartGroupGIDs 237 | 238 | 1C37FBAC04509CD000000102 239 | 1C37FAAC04509CD000000102 240 | 1C08E77C0454961000C914BD 241 | 1C37FABC05509CD000000102 242 | 1C37FABC05539CD112110102 243 | E2644B35053B69B200211256 244 | 1C37FABC04509CD000100104 245 | 1CC0EA4004350EF90044410B 246 | 1CC0EA4004350EF90041110B 247 | 248 | PBXProjectModuleGUID 249 | 1CE0B1FE06471DED0097A5F4 250 | PBXProjectModuleLabel 251 | Files 252 | PBXProjectStructureProvided 253 | yes 254 | PBXSmartGroupTreeModuleColumnData 255 | 256 | PBXSmartGroupTreeModuleColumnWidthsKey 257 | 258 | 208 259 | 260 | PBXSmartGroupTreeModuleColumnsKey_v4 261 | 262 | MainColumn 263 | 264 | 265 | PBXSmartGroupTreeModuleOutlineStateKey_v7 266 | 267 | PBXSmartGroupTreeModuleOutlineStateExpansionKey 268 | 269 | 08FB7794FE84155DC02AAC07 270 | 0A36774E0F7D287C00B4662A 271 | 08FB7795FE84155DC02AAC07 272 | 08FB779DFE84155DC02AAC07 273 | 1AB674ADFE9D54B511CA2CBB 274 | 1C37FBAC04509CD000000102 275 | 0A855C270F80C83300AEAB7A 276 | 0A855C390F80C92800AEAB7A 277 | 0A855E160F8112CE00AEAB7A 278 | 1C37FABC05509CD000000102 279 | 280 | PBXSmartGroupTreeModuleOutlineStateSelectionKey 281 | 282 | 283 | 6 284 | 3 285 | 0 286 | 287 | 288 | PBXSmartGroupTreeModuleOutlineStateVisibleRectKey 289 | {{0, 0}, {208, 519}} 290 | 291 | PBXTopSmartGroupGIDs 292 | 293 | XCIncludePerspectivesSwitch 294 | 295 | XCSharingToken 296 | com.apple.Xcode.GFSharingToken 297 | 298 | GeometryConfiguration 299 | 300 | Frame 301 | {{0, 0}, {225, 537}} 302 | GroupTreeTableConfiguration 303 | 304 | MainColumn 305 | 208 306 | 307 | RubberWindowFrame 308 | 353 89 910 578 0 0 1680 1028 309 | 310 | Module 311 | PBXSmartGroupTreeModule 312 | Proportion 313 | 225pt 314 | 315 | 316 | Dock 317 | 318 | 319 | BecomeActive 320 | 321 | ContentConfiguration 322 | 323 | PBXProjectModuleGUID 324 | 1CE0B20306471E060097A5F4 325 | PBXProjectModuleLabel 326 | Test.m 327 | PBXSplitModuleInNavigatorKey 328 | 329 | Split0 330 | 331 | PBXProjectModuleGUID 332 | 1CE0B20406471E060097A5F4 333 | PBXProjectModuleLabel 334 | Test.m 335 | _historyCapacity 336 | 0 337 | bookmark 338 | 0A8563890F81884800AEAB7A 339 | history 340 | 341 | 0A3677E80F7D3EAE00B4662A 342 | 0A855C970F80CD8700AEAB7A 343 | 0A855D910F80FECD00AEAB7A 344 | 0A8560080F81339F00AEAB7A 345 | 346 | prevStack 347 | 348 | 0A855C5C0F80CA9200AEAB7A 349 | 0A855C5E0F80CA9200AEAB7A 350 | 0A855C8B0F80CD3500AEAB7A 351 | 0A855C990F80CD8700AEAB7A 352 | 0A855C9A0F80CD8700AEAB7A 353 | 0A855C9C0F80CD8700AEAB7A 354 | 0A855D320F80F86300AEAB7A 355 | 0A855D3C0F80F8AE00AEAB7A 356 | 0A855D940F80FECD00AEAB7A 357 | 0A855D960F80FECD00AEAB7A 358 | 0A855D970F80FECD00AEAB7A 359 | 0A855D990F80FECD00AEAB7A 360 | 361 | 362 | SplitCount 363 | 1 364 | 365 | StatusBarVisibility 366 | 367 | 368 | GeometryConfiguration 369 | 370 | Frame 371 | {{0, 0}, {680, 372}} 372 | RubberWindowFrame 373 | 353 89 910 578 0 0 1680 1028 374 | 375 | Module 376 | PBXNavigatorGroup 377 | Proportion 378 | 372pt 379 | 380 | 381 | ContentConfiguration 382 | 383 | PBXProjectModuleGUID 384 | 1CE0B20506471E060097A5F4 385 | PBXProjectModuleLabel 386 | Detail 387 | 388 | GeometryConfiguration 389 | 390 | Frame 391 | {{0, 377}, {680, 160}} 392 | RubberWindowFrame 393 | 353 89 910 578 0 0 1680 1028 394 | 395 | Module 396 | XCDetailModule 397 | Proportion 398 | 160pt 399 | 400 | 401 | Proportion 402 | 680pt 403 | 404 | 405 | Name 406 | Project 407 | ServiceClasses 408 | 409 | XCModuleDock 410 | PBXSmartGroupTreeModule 411 | XCModuleDock 412 | PBXNavigatorGroup 413 | XCDetailModule 414 | 415 | TableOfContents 416 | 417 | 0A8559490F7E67E000AEAB7A 418 | 1CE0B1FE06471DED0097A5F4 419 | 0A85594A0F7E67E000AEAB7A 420 | 1CE0B20306471E060097A5F4 421 | 1CE0B20506471E060097A5F4 422 | 423 | ToolbarConfiguration 424 | xcode.toolbar.config.defaultV3 425 | 426 | 427 | ControllerClassBaseName 428 | 429 | IconName 430 | WindowOfProject 431 | Identifier 432 | perspective.morph 433 | IsVertical 434 | 0 435 | Layout 436 | 437 | 438 | BecomeActive 439 | 1 440 | ContentConfiguration 441 | 442 | PBXBottomSmartGroupGIDs 443 | 444 | 1C37FBAC04509CD000000102 445 | 1C37FAAC04509CD000000102 446 | 1C08E77C0454961000C914BD 447 | 1C37FABC05509CD000000102 448 | 1C37FABC05539CD112110102 449 | E2644B35053B69B200211256 450 | 1C37FABC04509CD000100104 451 | 1CC0EA4004350EF90044410B 452 | 1CC0EA4004350EF90041110B 453 | 454 | PBXProjectModuleGUID 455 | 11E0B1FE06471DED0097A5F4 456 | PBXProjectModuleLabel 457 | Files 458 | PBXProjectStructureProvided 459 | yes 460 | PBXSmartGroupTreeModuleColumnData 461 | 462 | PBXSmartGroupTreeModuleColumnWidthsKey 463 | 464 | 186 465 | 466 | PBXSmartGroupTreeModuleColumnsKey_v4 467 | 468 | MainColumn 469 | 470 | 471 | PBXSmartGroupTreeModuleOutlineStateKey_v7 472 | 473 | PBXSmartGroupTreeModuleOutlineStateExpansionKey 474 | 475 | 29B97314FDCFA39411CA2CEA 476 | 1C37FABC05509CD000000102 477 | 478 | PBXSmartGroupTreeModuleOutlineStateSelectionKey 479 | 480 | 481 | 0 482 | 483 | 484 | PBXSmartGroupTreeModuleOutlineStateVisibleRectKey 485 | {{0, 0}, {186, 337}} 486 | 487 | PBXTopSmartGroupGIDs 488 | 489 | XCIncludePerspectivesSwitch 490 | 1 491 | XCSharingToken 492 | com.apple.Xcode.GFSharingToken 493 | 494 | GeometryConfiguration 495 | 496 | Frame 497 | {{0, 0}, {203, 355}} 498 | GroupTreeTableConfiguration 499 | 500 | MainColumn 501 | 186 502 | 503 | RubberWindowFrame 504 | 373 269 690 397 0 0 1440 878 505 | 506 | Module 507 | PBXSmartGroupTreeModule 508 | Proportion 509 | 100% 510 | 511 | 512 | Name 513 | Morph 514 | PreferredWidth 515 | 300 516 | ServiceClasses 517 | 518 | XCModuleDock 519 | PBXSmartGroupTreeModule 520 | 521 | TableOfContents 522 | 523 | 11E0B1FE06471DED0097A5F4 524 | 525 | ToolbarConfiguration 526 | xcode.toolbar.config.default.shortV3 527 | 528 | 529 | PerspectivesBarVisible 530 | 531 | ShelfIsVisible 532 | 533 | SourceDescription 534 | file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' 535 | StatusbarIsVisible 536 | 537 | TimeStamp 538 | 0.0 539 | ToolbarDisplayMode 540 | 1 541 | ToolbarIsVisible 542 | 543 | ToolbarSizeMode 544 | 1 545 | Type 546 | Perspectives 547 | UpdateMessage 548 | The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? 549 | WindowJustification 550 | 5 551 | WindowOrderList 552 | 553 | 0A855B040F7EDD7F00AEAB7A 554 | 0A855B050F7EDD7F00AEAB7A 555 | 1CD10A99069EF8BA00B06720 556 | 0A3677780F7D29FC00B4662A 557 | /Users/dmitry/Projects/EllipticLicense/Test/Test.xcodeproj 558 | 1C78EAAD065D492600B07095 559 | 560 | WindowString 561 | 353 89 910 578 0 0 1680 1028 562 | WindowToolsV3 563 | 564 | 565 | FirstTimeWindowDisplayed 566 | 567 | Identifier 568 | windowTool.build 569 | IsVertical 570 | 571 | Layout 572 | 573 | 574 | Dock 575 | 576 | 577 | BecomeActive 578 | 579 | ContentConfiguration 580 | 581 | PBXProjectModuleGUID 582 | 1CD0528F0623707200166675 583 | PBXProjectModuleLabel 584 | Test.m 585 | StatusBarVisibility 586 | 587 | 588 | GeometryConfiguration 589 | 590 | Frame 591 | {{0, 0}, {845, 277}} 592 | RubberWindowFrame 593 | 546 196 845 559 0 0 1680 1028 594 | 595 | Module 596 | PBXNavigatorGroup 597 | Proportion 598 | 277pt 599 | 600 | 601 | ContentConfiguration 602 | 603 | PBXProjectModuleGUID 604 | XCMainBuildResultsModuleGUID 605 | PBXProjectModuleLabel 606 | Build 607 | XCBuildResultsTrigger_Collapse 608 | 1021 609 | XCBuildResultsTrigger_Open 610 | 1011 611 | 612 | GeometryConfiguration 613 | 614 | Frame 615 | {{0, 282}, {845, 236}} 616 | RubberWindowFrame 617 | 546 196 845 559 0 0 1680 1028 618 | 619 | Module 620 | PBXBuildResultsModule 621 | Proportion 622 | 236pt 623 | 624 | 625 | Proportion 626 | 518pt 627 | 628 | 629 | Name 630 | Build Results 631 | ServiceClasses 632 | 633 | PBXBuildResultsModule 634 | 635 | StatusbarIsVisible 636 | 637 | TableOfContents 638 | 639 | 0A3677780F7D29FC00B4662A 640 | 0A85594B0F7E67E000AEAB7A 641 | 1CD0528F0623707200166675 642 | XCMainBuildResultsModuleGUID 643 | 644 | ToolbarConfiguration 645 | xcode.toolbar.config.buildV3 646 | WindowString 647 | 546 196 845 559 0 0 1680 1028 648 | WindowToolGUID 649 | 0A3677780F7D29FC00B4662A 650 | WindowToolIsVisible 651 | 652 | 653 | 654 | FirstTimeWindowDisplayed 655 | 656 | Identifier 657 | windowTool.debugger 658 | IsVertical 659 | 660 | Layout 661 | 662 | 663 | Dock 664 | 665 | 666 | ContentConfiguration 667 | 668 | Debugger 669 | 670 | HorizontalSplitView 671 | 672 | _collapsingFrameDimension 673 | 0.0 674 | _indexOfCollapsedView 675 | 0 676 | _percentageOfCollapsedView 677 | 0.0 678 | isCollapsed 679 | yes 680 | sizes 681 | 682 | {{0, 0}, {316, 201}} 683 | {{316, 0}, {378, 201}} 684 | 685 | 686 | VerticalSplitView 687 | 688 | _collapsingFrameDimension 689 | 0.0 690 | _indexOfCollapsedView 691 | 0 692 | _percentageOfCollapsedView 693 | 0.0 694 | isCollapsed 695 | yes 696 | sizes 697 | 698 | {{0, 0}, {694, 201}} 699 | {{0, 201}, {694, 180}} 700 | 701 | 702 | 703 | LauncherConfigVersion 704 | 8 705 | PBXProjectModuleGUID 706 | 1C162984064C10D400B95A72 707 | PBXProjectModuleLabel 708 | Debug - GLUTExamples (Underwater) 709 | 710 | GeometryConfiguration 711 | 712 | DebugConsoleVisible 713 | None 714 | DebugConsoleWindowFrame 715 | {{200, 200}, {500, 300}} 716 | DebugSTDIOWindowFrame 717 | {{200, 200}, {500, 300}} 718 | Frame 719 | {{0, 0}, {694, 381}} 720 | PBXDebugSessionStackFrameViewKey 721 | 722 | DebugVariablesTableConfiguration 723 | 724 | Name 725 | 120 726 | Value 727 | 85 728 | Summary 729 | 148 730 | 731 | Frame 732 | {{316, 0}, {378, 201}} 733 | RubberWindowFrame 734 | 546 333 694 422 0 0 1680 1028 735 | 736 | RubberWindowFrame 737 | 546 333 694 422 0 0 1680 1028 738 | 739 | Module 740 | PBXDebugSessionModule 741 | Proportion 742 | 381pt 743 | 744 | 745 | Proportion 746 | 381pt 747 | 748 | 749 | Name 750 | Debugger 751 | ServiceClasses 752 | 753 | PBXDebugSessionModule 754 | 755 | StatusbarIsVisible 756 | 757 | TableOfContents 758 | 759 | 1CD10A99069EF8BA00B06720 760 | 0A85594C0F7E67E000AEAB7A 761 | 1C162984064C10D400B95A72 762 | 0A85594D0F7E67E000AEAB7A 763 | 0A85594E0F7E67E000AEAB7A 764 | 0A85594F0F7E67E000AEAB7A 765 | 0A8559500F7E67E000AEAB7A 766 | 0A8559510F7E67E000AEAB7A 767 | 768 | ToolbarConfiguration 769 | xcode.toolbar.config.debugV3 770 | WindowString 771 | 546 333 694 422 0 0 1680 1028 772 | WindowToolGUID 773 | 1CD10A99069EF8BA00B06720 774 | WindowToolIsVisible 775 | 776 | 777 | 778 | Identifier 779 | windowTool.find 780 | Layout 781 | 782 | 783 | Dock 784 | 785 | 786 | Dock 787 | 788 | 789 | ContentConfiguration 790 | 791 | PBXProjectModuleGUID 792 | 1CDD528C0622207200134675 793 | PBXProjectModuleLabel 794 | <No Editor> 795 | PBXSplitModuleInNavigatorKey 796 | 797 | Split0 798 | 799 | PBXProjectModuleGUID 800 | 1CD0528D0623707200166675 801 | 802 | SplitCount 803 | 1 804 | 805 | StatusBarVisibility 806 | 1 807 | 808 | GeometryConfiguration 809 | 810 | Frame 811 | {{0, 0}, {781, 167}} 812 | RubberWindowFrame 813 | 62 385 781 470 0 0 1440 878 814 | 815 | Module 816 | PBXNavigatorGroup 817 | Proportion 818 | 781pt 819 | 820 | 821 | Proportion 822 | 50% 823 | 824 | 825 | BecomeActive 826 | 1 827 | ContentConfiguration 828 | 829 | PBXProjectModuleGUID 830 | 1CD0528E0623707200166675 831 | PBXProjectModuleLabel 832 | Project Find 833 | 834 | GeometryConfiguration 835 | 836 | Frame 837 | {{8, 0}, {773, 254}} 838 | RubberWindowFrame 839 | 62 385 781 470 0 0 1440 878 840 | 841 | Module 842 | PBXProjectFindModule 843 | Proportion 844 | 50% 845 | 846 | 847 | Proportion 848 | 428pt 849 | 850 | 851 | Name 852 | Project Find 853 | ServiceClasses 854 | 855 | PBXProjectFindModule 856 | 857 | StatusbarIsVisible 858 | 1 859 | TableOfContents 860 | 861 | 1C530D57069F1CE1000CFCEE 862 | 1C530D58069F1CE1000CFCEE 863 | 1C530D59069F1CE1000CFCEE 864 | 1CDD528C0622207200134675 865 | 1C530D5A069F1CE1000CFCEE 866 | 1CE0B1FE06471DED0097A5F4 867 | 1CD0528E0623707200166675 868 | 869 | WindowString 870 | 62 385 781 470 0 0 1440 878 871 | WindowToolGUID 872 | 1C530D57069F1CE1000CFCEE 873 | WindowToolIsVisible 874 | 0 875 | 876 | 877 | Identifier 878 | MENUSEPARATOR 879 | 880 | 881 | FirstTimeWindowDisplayed 882 | 883 | Identifier 884 | windowTool.debuggerConsole 885 | IsVertical 886 | 887 | Layout 888 | 889 | 890 | Dock 891 | 892 | 893 | BecomeActive 894 | 895 | ContentConfiguration 896 | 897 | PBXProjectModuleGUID 898 | 1C78EAAC065D492600B07095 899 | PBXProjectModuleLabel 900 | Debugger Console 901 | 902 | GeometryConfiguration 903 | 904 | Frame 905 | {{0, 0}, {650, 209}} 906 | RubberWindowFrame 907 | 939 757 650 250 0 0 1680 1028 908 | 909 | Module 910 | PBXDebugCLIModule 911 | Proportion 912 | 209pt 913 | 914 | 915 | Proportion 916 | 209pt 917 | 918 | 919 | Name 920 | Debugger Console 921 | ServiceClasses 922 | 923 | PBXDebugCLIModule 924 | 925 | StatusbarIsVisible 926 | 927 | TableOfContents 928 | 929 | 1C78EAAD065D492600B07095 930 | 0A8559520F7E67E000AEAB7A 931 | 1C78EAAC065D492600B07095 932 | 933 | ToolbarConfiguration 934 | xcode.toolbar.config.consoleV3 935 | WindowString 936 | 939 757 650 250 0 0 1680 1028 937 | WindowToolGUID 938 | 1C78EAAD065D492600B07095 939 | WindowToolIsVisible 940 | 941 | 942 | 943 | Identifier 944 | windowTool.snapshots 945 | Layout 946 | 947 | 948 | Dock 949 | 950 | 951 | Module 952 | XCSnapshotModule 953 | Proportion 954 | 100% 955 | 956 | 957 | Proportion 958 | 100% 959 | 960 | 961 | Name 962 | Snapshots 963 | ServiceClasses 964 | 965 | XCSnapshotModule 966 | 967 | StatusbarIsVisible 968 | Yes 969 | ToolbarConfiguration 970 | xcode.toolbar.config.snapshots 971 | WindowString 972 | 315 824 300 550 0 0 1440 878 973 | WindowToolIsVisible 974 | Yes 975 | 976 | 977 | Identifier 978 | windowTool.scm 979 | Layout 980 | 981 | 982 | Dock 983 | 984 | 985 | ContentConfiguration 986 | 987 | PBXProjectModuleGUID 988 | 1C78EAB2065D492600B07095 989 | PBXProjectModuleLabel 990 | <No Editor> 991 | PBXSplitModuleInNavigatorKey 992 | 993 | Split0 994 | 995 | PBXProjectModuleGUID 996 | 1C78EAB3065D492600B07095 997 | 998 | SplitCount 999 | 1 1000 | 1001 | StatusBarVisibility 1002 | 1 1003 | 1004 | GeometryConfiguration 1005 | 1006 | Frame 1007 | {{0, 0}, {452, 0}} 1008 | RubberWindowFrame 1009 | 743 379 452 308 0 0 1280 1002 1010 | 1011 | Module 1012 | PBXNavigatorGroup 1013 | Proportion 1014 | 0pt 1015 | 1016 | 1017 | BecomeActive 1018 | 1 1019 | ContentConfiguration 1020 | 1021 | PBXProjectModuleGUID 1022 | 1CD052920623707200166675 1023 | PBXProjectModuleLabel 1024 | SCM 1025 | 1026 | GeometryConfiguration 1027 | 1028 | ConsoleFrame 1029 | {{0, 259}, {452, 0}} 1030 | Frame 1031 | {{0, 7}, {452, 259}} 1032 | RubberWindowFrame 1033 | 743 379 452 308 0 0 1280 1002 1034 | TableConfiguration 1035 | 1036 | Status 1037 | 30 1038 | FileName 1039 | 199 1040 | Path 1041 | 197.0950012207031 1042 | 1043 | TableFrame 1044 | {{0, 0}, {452, 250}} 1045 | 1046 | Module 1047 | PBXCVSModule 1048 | Proportion 1049 | 262pt 1050 | 1051 | 1052 | Proportion 1053 | 266pt 1054 | 1055 | 1056 | Name 1057 | SCM 1058 | ServiceClasses 1059 | 1060 | PBXCVSModule 1061 | 1062 | StatusbarIsVisible 1063 | 1 1064 | TableOfContents 1065 | 1066 | 1C78EAB4065D492600B07095 1067 | 1C78EAB5065D492600B07095 1068 | 1C78EAB2065D492600B07095 1069 | 1CD052920623707200166675 1070 | 1071 | ToolbarConfiguration 1072 | xcode.toolbar.config.scm 1073 | WindowString 1074 | 743 379 452 308 0 0 1280 1002 1075 | 1076 | 1077 | Identifier 1078 | windowTool.breakpoints 1079 | IsVertical 1080 | 0 1081 | Layout 1082 | 1083 | 1084 | Dock 1085 | 1086 | 1087 | BecomeActive 1088 | 1 1089 | ContentConfiguration 1090 | 1091 | PBXBottomSmartGroupGIDs 1092 | 1093 | 1C77FABC04509CD000000102 1094 | 1095 | PBXProjectModuleGUID 1096 | 1CE0B1FE06471DED0097A5F4 1097 | PBXProjectModuleLabel 1098 | Files 1099 | PBXProjectStructureProvided 1100 | no 1101 | PBXSmartGroupTreeModuleColumnData 1102 | 1103 | PBXSmartGroupTreeModuleColumnWidthsKey 1104 | 1105 | 168 1106 | 1107 | PBXSmartGroupTreeModuleColumnsKey_v4 1108 | 1109 | MainColumn 1110 | 1111 | 1112 | PBXSmartGroupTreeModuleOutlineStateKey_v7 1113 | 1114 | PBXSmartGroupTreeModuleOutlineStateExpansionKey 1115 | 1116 | 1C77FABC04509CD000000102 1117 | 1118 | PBXSmartGroupTreeModuleOutlineStateSelectionKey 1119 | 1120 | 1121 | 0 1122 | 1123 | 1124 | PBXSmartGroupTreeModuleOutlineStateVisibleRectKey 1125 | {{0, 0}, {168, 350}} 1126 | 1127 | PBXTopSmartGroupGIDs 1128 | 1129 | XCIncludePerspectivesSwitch 1130 | 0 1131 | 1132 | GeometryConfiguration 1133 | 1134 | Frame 1135 | {{0, 0}, {185, 368}} 1136 | GroupTreeTableConfiguration 1137 | 1138 | MainColumn 1139 | 168 1140 | 1141 | RubberWindowFrame 1142 | 315 424 744 409 0 0 1440 878 1143 | 1144 | Module 1145 | PBXSmartGroupTreeModule 1146 | Proportion 1147 | 185pt 1148 | 1149 | 1150 | ContentConfiguration 1151 | 1152 | PBXProjectModuleGUID 1153 | 1CA1AED706398EBD00589147 1154 | PBXProjectModuleLabel 1155 | Detail 1156 | 1157 | GeometryConfiguration 1158 | 1159 | Frame 1160 | {{190, 0}, {554, 368}} 1161 | RubberWindowFrame 1162 | 315 424 744 409 0 0 1440 878 1163 | 1164 | Module 1165 | XCDetailModule 1166 | Proportion 1167 | 554pt 1168 | 1169 | 1170 | Proportion 1171 | 368pt 1172 | 1173 | 1174 | MajorVersion 1175 | 3 1176 | MinorVersion 1177 | 0 1178 | Name 1179 | Breakpoints 1180 | ServiceClasses 1181 | 1182 | PBXSmartGroupTreeModule 1183 | XCDetailModule 1184 | 1185 | StatusbarIsVisible 1186 | 1 1187 | TableOfContents 1188 | 1189 | 1CDDB66807F98D9800BB5817 1190 | 1CDDB66907F98D9800BB5817 1191 | 1CE0B1FE06471DED0097A5F4 1192 | 1CA1AED706398EBD00589147 1193 | 1194 | ToolbarConfiguration 1195 | xcode.toolbar.config.breakpointsV3 1196 | WindowString 1197 | 315 424 744 409 0 0 1440 878 1198 | WindowToolGUID 1199 | 1CDDB66807F98D9800BB5817 1200 | WindowToolIsVisible 1201 | 1 1202 | 1203 | 1204 | Identifier 1205 | windowTool.debugAnimator 1206 | Layout 1207 | 1208 | 1209 | Dock 1210 | 1211 | 1212 | Module 1213 | PBXNavigatorGroup 1214 | Proportion 1215 | 100% 1216 | 1217 | 1218 | Proportion 1219 | 100% 1220 | 1221 | 1222 | Name 1223 | Debug Visualizer 1224 | ServiceClasses 1225 | 1226 | PBXNavigatorGroup 1227 | 1228 | StatusbarIsVisible 1229 | 1 1230 | ToolbarConfiguration 1231 | xcode.toolbar.config.debugAnimatorV3 1232 | WindowString 1233 | 100 100 700 500 0 0 1280 1002 1234 | 1235 | 1236 | Identifier 1237 | windowTool.bookmarks 1238 | Layout 1239 | 1240 | 1241 | Dock 1242 | 1243 | 1244 | Module 1245 | PBXBookmarksModule 1246 | Proportion 1247 | 100% 1248 | 1249 | 1250 | Proportion 1251 | 100% 1252 | 1253 | 1254 | Name 1255 | Bookmarks 1256 | ServiceClasses 1257 | 1258 | PBXBookmarksModule 1259 | 1260 | StatusbarIsVisible 1261 | 0 1262 | WindowString 1263 | 538 42 401 187 0 0 1280 1002 1264 | 1265 | 1266 | Identifier 1267 | windowTool.projectFormatConflicts 1268 | Layout 1269 | 1270 | 1271 | Dock 1272 | 1273 | 1274 | Module 1275 | XCProjectFormatConflictsModule 1276 | Proportion 1277 | 100% 1278 | 1279 | 1280 | Proportion 1281 | 100% 1282 | 1283 | 1284 | Name 1285 | Project Format Conflicts 1286 | ServiceClasses 1287 | 1288 | XCProjectFormatConflictsModule 1289 | 1290 | StatusbarIsVisible 1291 | 0 1292 | WindowContentMinSize 1293 | 450 300 1294 | WindowString 1295 | 50 850 472 307 0 0 1440 877 1296 | 1297 | 1298 | Identifier 1299 | windowTool.classBrowser 1300 | Layout 1301 | 1302 | 1303 | Dock 1304 | 1305 | 1306 | BecomeActive 1307 | 1 1308 | ContentConfiguration 1309 | 1310 | OptionsSetName 1311 | Hierarchy, all classes 1312 | PBXProjectModuleGUID 1313 | 1CA6456E063B45B4001379D8 1314 | PBXProjectModuleLabel 1315 | Class Browser - NSObject 1316 | 1317 | GeometryConfiguration 1318 | 1319 | ClassesFrame 1320 | {{0, 0}, {374, 96}} 1321 | ClassesTreeTableConfiguration 1322 | 1323 | PBXClassNameColumnIdentifier 1324 | 208 1325 | PBXClassBookColumnIdentifier 1326 | 22 1327 | 1328 | Frame 1329 | {{0, 0}, {630, 331}} 1330 | MembersFrame 1331 | {{0, 105}, {374, 395}} 1332 | MembersTreeTableConfiguration 1333 | 1334 | PBXMemberTypeIconColumnIdentifier 1335 | 22 1336 | PBXMemberNameColumnIdentifier 1337 | 216 1338 | PBXMemberTypeColumnIdentifier 1339 | 97 1340 | PBXMemberBookColumnIdentifier 1341 | 22 1342 | 1343 | PBXModuleWindowStatusBarHidden2 1344 | 1 1345 | RubberWindowFrame 1346 | 385 179 630 352 0 0 1440 878 1347 | 1348 | Module 1349 | PBXClassBrowserModule 1350 | Proportion 1351 | 332pt 1352 | 1353 | 1354 | Proportion 1355 | 332pt 1356 | 1357 | 1358 | Name 1359 | Class Browser 1360 | ServiceClasses 1361 | 1362 | PBXClassBrowserModule 1363 | 1364 | StatusbarIsVisible 1365 | 0 1366 | TableOfContents 1367 | 1368 | 1C0AD2AF069F1E9B00FABCE6 1369 | 1C0AD2B0069F1E9B00FABCE6 1370 | 1CA6456E063B45B4001379D8 1371 | 1372 | ToolbarConfiguration 1373 | xcode.toolbar.config.classbrowser 1374 | WindowString 1375 | 385 179 630 352 0 0 1440 878 1376 | WindowToolGUID 1377 | 1C0AD2AF069F1E9B00FABCE6 1378 | WindowToolIsVisible 1379 | 0 1380 | 1381 | 1382 | Identifier 1383 | windowTool.refactoring 1384 | IncludeInToolsMenu 1385 | 0 1386 | Layout 1387 | 1388 | 1389 | Dock 1390 | 1391 | 1392 | BecomeActive 1393 | 1 1394 | GeometryConfiguration 1395 | 1396 | Frame 1397 | {0, 0}, {500, 335} 1398 | RubberWindowFrame 1399 | {0, 0}, {500, 335} 1400 | 1401 | Module 1402 | XCRefactoringModule 1403 | Proportion 1404 | 100% 1405 | 1406 | 1407 | Proportion 1408 | 100% 1409 | 1410 | 1411 | Name 1412 | Refactoring 1413 | ServiceClasses 1414 | 1415 | XCRefactoringModule 1416 | 1417 | WindowString 1418 | 200 200 500 356 0 0 1920 1200 1419 | 1420 | 1421 | 1422 | 1423 | -------------------------------------------------------------------------------- /Test/Test.xcodeproj/dmitry.pbxuser: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 4 | activeBuildConfigurationName = Debug; 5 | activeExecutable = 0A36774B0F7D287100B4662A /* Test */; 6 | activeTarget = 8DD76F960486AA7600D96B5E /* Test */; 7 | addToTargets = ( 8 | 8DD76F960486AA7600D96B5E /* Test */, 9 | ); 10 | breakpoints = ( 11 | ); 12 | codeSenseManager = 0A3677550F7D287C00B4662A /* Code sense */; 13 | executables = ( 14 | 0A36774B0F7D287100B4662A /* Test */, 15 | ); 16 | perUserDictionary = { 17 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { 18 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 19 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 20 | PBXFileTableDataSourceColumnWidthsKey = ( 21 | 20, 22 | 441, 23 | 20, 24 | 48, 25 | 43, 26 | 43, 27 | 20, 28 | ); 29 | PBXFileTableDataSourceColumnsKey = ( 30 | PBXFileDataSource_FiletypeID, 31 | PBXFileDataSource_Filename_ColumnID, 32 | PBXFileDataSource_Built_ColumnID, 33 | PBXFileDataSource_ObjectSize_ColumnID, 34 | PBXFileDataSource_Errors_ColumnID, 35 | PBXFileDataSource_Warnings_ColumnID, 36 | PBXFileDataSource_Target_ColumnID, 37 | ); 38 | }; 39 | PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { 40 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 41 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 42 | PBXFileTableDataSourceColumnWidthsKey = ( 43 | 20, 44 | 401, 45 | 60, 46 | 20, 47 | 48, 48 | 43, 49 | 43, 50 | ); 51 | PBXFileTableDataSourceColumnsKey = ( 52 | PBXFileDataSource_FiletypeID, 53 | PBXFileDataSource_Filename_ColumnID, 54 | PBXTargetDataSource_PrimaryAttribute, 55 | PBXFileDataSource_Built_ColumnID, 56 | PBXFileDataSource_ObjectSize_ColumnID, 57 | PBXFileDataSource_Errors_ColumnID, 58 | PBXFileDataSource_Warnings_ColumnID, 59 | ); 60 | }; 61 | PBXPerProjectTemplateStateSaveDate = 259942074; 62 | PBXWorkspaceStateSaveDate = 259942074; 63 | }; 64 | perUserProjectItems = { 65 | 0A3677E80F7D3EAE00B4662A /* PBXTextBookmark */ = 0A3677E80F7D3EAE00B4662A /* PBXTextBookmark */; 66 | 0A855C5C0F80CA9200AEAB7A /* PBXTextBookmark */ = 0A855C5C0F80CA9200AEAB7A /* PBXTextBookmark */; 67 | 0A855C5E0F80CA9200AEAB7A /* PBXTextBookmark */ = 0A855C5E0F80CA9200AEAB7A /* PBXTextBookmark */; 68 | 0A855C8B0F80CD3500AEAB7A /* PBXTextBookmark */ = 0A855C8B0F80CD3500AEAB7A /* PBXTextBookmark */; 69 | 0A855C970F80CD8700AEAB7A /* PBXTextBookmark */ = 0A855C970F80CD8700AEAB7A /* PBXTextBookmark */; 70 | 0A855C990F80CD8700AEAB7A /* PBXTextBookmark */ = 0A855C990F80CD8700AEAB7A /* PBXTextBookmark */; 71 | 0A855C9A0F80CD8700AEAB7A /* PBXTextBookmark */ = 0A855C9A0F80CD8700AEAB7A /* PBXTextBookmark */; 72 | 0A855C9C0F80CD8700AEAB7A /* PBXTextBookmark */ = 0A855C9C0F80CD8700AEAB7A /* PBXTextBookmark */; 73 | 0A855D320F80F86300AEAB7A /* PBXTextBookmark */ = 0A855D320F80F86300AEAB7A /* PBXTextBookmark */; 74 | 0A855D3C0F80F8AE00AEAB7A /* PBXTextBookmark */ = 0A855D3C0F80F8AE00AEAB7A /* PBXTextBookmark */; 75 | 0A855D910F80FECD00AEAB7A /* PBXTextBookmark */ = 0A855D910F80FECD00AEAB7A /* PBXTextBookmark */; 76 | 0A855D940F80FECD00AEAB7A /* PBXTextBookmark */ = 0A855D940F80FECD00AEAB7A /* PBXTextBookmark */; 77 | 0A855D960F80FECD00AEAB7A /* PBXTextBookmark */ = 0A855D960F80FECD00AEAB7A /* PBXTextBookmark */; 78 | 0A855D970F80FECD00AEAB7A /* PBXTextBookmark */ = 0A855D970F80FECD00AEAB7A /* PBXTextBookmark */; 79 | 0A855D990F80FECD00AEAB7A /* PBXTextBookmark */ = 0A855D990F80FECD00AEAB7A /* PBXTextBookmark */; 80 | 0A8560080F81339F00AEAB7A /* PBXTextBookmark */ = 0A8560080F81339F00AEAB7A /* PBXTextBookmark */; 81 | 0A8563890F81884800AEAB7A /* PBXTextBookmark */ = 0A8563890F81884800AEAB7A /* PBXTextBookmark */; 82 | }; 83 | sourceControlManager = 0A3677540F7D287C00B4662A /* Source Control */; 84 | userBuildSettings = { 85 | }; 86 | }; 87 | 08FB7796FE84155DC02AAC07 /* Test.m */ = { 88 | uiCtxt = { 89 | sepNavIntBoundsRect = "{{0, 0}, {784, 585}}"; 90 | sepNavSelRange = "{968, 0}"; 91 | sepNavVisRange = "{320, 896}"; 92 | }; 93 | }; 94 | 0A36774B0F7D287100B4662A /* Test */ = { 95 | isa = PBXExecutable; 96 | activeArgIndices = ( 97 | ); 98 | argumentStrings = ( 99 | ); 100 | autoAttachOnCrash = 1; 101 | breakpointsEnabled = 0; 102 | configStateDict = { 103 | }; 104 | customDataFormattersEnabled = 1; 105 | debuggerPlugin = GDBDebugging; 106 | disassemblyDisplayState = 0; 107 | dylibVariantSuffix = ""; 108 | enableDebugStr = 1; 109 | environmentEntries = ( 110 | ); 111 | executableSystemSymbolLevel = 0; 112 | executableUserSymbolLevel = 0; 113 | libgmallocEnabled = 0; 114 | name = Test; 115 | savedGlobals = { 116 | }; 117 | sourceDirectories = ( 118 | ); 119 | variableFormatDictionary = { 120 | }; 121 | }; 122 | 0A3677540F7D287C00B4662A /* Source Control */ = { 123 | isa = PBXSourceControlManager; 124 | fallbackIsa = XCSourceControlManager; 125 | isSCMEnabled = 0; 126 | scmConfiguration = { 127 | }; 128 | }; 129 | 0A3677550F7D287C00B4662A /* Code sense */ = { 130 | isa = PBXCodeSenseManager; 131 | indexTemplatePath = ""; 132 | }; 133 | 0A3677E80F7D3EAE00B4662A /* PBXTextBookmark */ = { 134 | isa = PBXTextBookmark; 135 | fRef = 0A3677E90F7D3EAE00B4662A /* t_pkey.c */; 136 | name = "t_pkey.c: 540"; 137 | rLen = 0; 138 | rLoc = 14088; 139 | rType = 0; 140 | vrLen = 550; 141 | vrLoc = 13872; 142 | }; 143 | 0A3677E90F7D3EAE00B4662A /* t_pkey.c */ = { 144 | isa = PBXFileReference; 145 | lastKnownFileType = sourcecode.c.c; 146 | name = t_pkey.c; 147 | path = /Users/dmitry/Projects/EllipticLicense/openssl/crypto/asn1/t_pkey.c; 148 | sourceTree = ""; 149 | }; 150 | 0A36791E0F7E489D00B4662A /* EllipticLicense.h */ = { 151 | uiCtxt = { 152 | sepNavIntBoundsRect = "{{0, 0}, {619, 515}}"; 153 | sepNavSelRange = "{1114, 0}"; 154 | sepNavVisRange = "{0, 1120}"; 155 | }; 156 | }; 157 | 0A855C5C0F80CA9200AEAB7A /* PBXTextBookmark */ = { 158 | isa = PBXTextBookmark; 159 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 160 | name = "Test.m: 18"; 161 | rLen = 0; 162 | rLoc = 1020; 163 | rType = 0; 164 | vrLen = 997; 165 | vrLoc = 230; 166 | }; 167 | 0A855C5E0F80CA9200AEAB7A /* PBXTextBookmark */ = { 168 | isa = PBXTextBookmark; 169 | fRef = 0A855C5F0F80CA9200AEAB7A /* EllipticLicense.m */; 170 | name = "EllipticLicense.m: 1"; 171 | rLen = 0; 172 | rLoc = 0; 173 | rType = 0; 174 | vrLen = 960; 175 | vrLoc = 0; 176 | }; 177 | 0A855C5F0F80CA9200AEAB7A /* EllipticLicense.m */ = { 178 | isa = PBXFileReference; 179 | name = EllipticLicense.m; 180 | path = /Users/dmitry/Projects/EllipticLicense/Framework/EllipticLicense.m; 181 | sourceTree = ""; 182 | }; 183 | 0A855C730F80CC7E00AEAB7A /* EllipticLicense.m */ = { 184 | isa = PBXFileReference; 185 | lastKnownFileType = sourcecode.c.objc; 186 | name = EllipticLicense.m; 187 | path = /Users/dmitry/Projects/EllipticLicense/Framework/EllipticLicense.m; 188 | sourceTree = ""; 189 | uiCtxt = { 190 | sepNavIntBoundsRect = "{{0, 0}, {619, 3150}}"; 191 | sepNavSelRange = "{2019, 0}"; 192 | sepNavVisRange = "{1703, 529}"; 193 | }; 194 | }; 195 | 0A855C8B0F80CD3500AEAB7A /* PBXTextBookmark */ = { 196 | isa = PBXTextBookmark; 197 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 198 | name = "Test.m: 16"; 199 | rLen = 0; 200 | rLoc = 873; 201 | rType = 0; 202 | vrLen = 911; 203 | vrLoc = 172; 204 | }; 205 | 0A855C970F80CD8700AEAB7A /* PBXTextBookmark */ = { 206 | isa = PBXTextBookmark; 207 | fRef = 0A855C730F80CC7E00AEAB7A /* EllipticLicense.m */; 208 | name = "EllipticLicense.m: 76"; 209 | rLen = 0; 210 | rLoc = 1554; 211 | rType = 0; 212 | vrLen = 529; 213 | vrLoc = 1703; 214 | }; 215 | 0A855C990F80CD8700AEAB7A /* PBXTextBookmark */ = { 216 | isa = PBXTextBookmark; 217 | fRef = 0A855C730F80CC7E00AEAB7A /* EllipticLicense.m */; 218 | name = "EllipticLicense.m: 57"; 219 | rLen = 0; 220 | rLoc = 1554; 221 | rType = 0; 222 | vrLen = 658; 223 | vrLoc = 1400; 224 | }; 225 | 0A855C9A0F80CD8700AEAB7A /* PBXTextBookmark */ = { 226 | isa = PBXTextBookmark; 227 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 228 | name = "Test.m: 16"; 229 | rLen = 0; 230 | rLoc = 873; 231 | rType = 0; 232 | vrLen = 974; 233 | vrLoc = 314; 234 | }; 235 | 0A855C9C0F80CD8700AEAB7A /* PBXTextBookmark */ = { 236 | isa = PBXTextBookmark; 237 | fRef = 0A855C730F80CC7E00AEAB7A /* EllipticLicense.m */; 238 | name = "EllipticLicense.m: 76"; 239 | rLen = 0; 240 | rLoc = 1554; 241 | rType = 0; 242 | vrLen = 529; 243 | vrLoc = 1703; 244 | }; 245 | 0A855D320F80F86300AEAB7A /* PBXTextBookmark */ = { 246 | isa = PBXTextBookmark; 247 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 248 | name = "Test.m: 17"; 249 | rLen = 0; 250 | rLoc = 969; 251 | rType = 0; 252 | vrLen = 884; 253 | vrLoc = 556; 254 | }; 255 | 0A855D3C0F80F8AE00AEAB7A /* PBXTextBookmark */ = { 256 | isa = PBXTextBookmark; 257 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 258 | name = "Test.m: 17"; 259 | rLen = 22; 260 | rLoc = 946; 261 | rType = 0; 262 | vrLen = 903; 263 | vrLoc = 556; 264 | }; 265 | 0A855D910F80FECD00AEAB7A /* PBXTextBookmark */ = { 266 | isa = PBXTextBookmark; 267 | fRef = 32A70AAB03705E1F00C91783 /* Test_Prefix.pch */; 268 | name = "Test_Prefix.pch: 1"; 269 | rLen = 0; 270 | rLoc = 0; 271 | rType = 0; 272 | vrLen = 150; 273 | vrLoc = 0; 274 | }; 275 | 0A855D940F80FECD00AEAB7A /* PBXTextBookmark */ = { 276 | isa = PBXTextBookmark; 277 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 278 | name = "Test.m: 28"; 279 | rLen = 0; 280 | rLoc = 1302; 281 | rType = 0; 282 | vrLen = 1313; 283 | vrLoc = 232; 284 | }; 285 | 0A855D960F80FECD00AEAB7A /* PBXTextBookmark */ = { 286 | isa = PBXTextBookmark; 287 | fRef = 32A70AAB03705E1F00C91783 /* Test_Prefix.pch */; 288 | name = "Test_Prefix.pch: 1"; 289 | rLen = 0; 290 | rLoc = 0; 291 | rType = 0; 292 | vrLen = 150; 293 | vrLoc = 0; 294 | }; 295 | 0A855D970F80FECD00AEAB7A /* PBXTextBookmark */ = { 296 | isa = PBXTextBookmark; 297 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 298 | name = "Test.m: 21"; 299 | rLen = 0; 300 | rLoc = 1037; 301 | rType = 0; 302 | vrLen = 1317; 303 | vrLoc = 230; 304 | }; 305 | 0A855D990F80FECD00AEAB7A /* PBXTextBookmark */ = { 306 | isa = PBXTextBookmark; 307 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 308 | name = "Test.m: 28"; 309 | rLen = 0; 310 | rLoc = 1364; 311 | rType = 0; 312 | vrLen = 1317; 313 | vrLoc = 230; 314 | }; 315 | 0A8560080F81339F00AEAB7A /* PBXTextBookmark */ = { 316 | isa = PBXTextBookmark; 317 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 318 | name = "Test.m: 18"; 319 | rLen = 0; 320 | rLoc = 985; 321 | rType = 0; 322 | vrLen = 988; 323 | vrLoc = 230; 324 | }; 325 | 0A8563890F81884800AEAB7A /* PBXTextBookmark */ = { 326 | isa = PBXTextBookmark; 327 | fRef = 08FB7796FE84155DC02AAC07 /* Test.m */; 328 | name = "Test.m: 26"; 329 | rLen = 0; 330 | rLoc = 1217; 331 | rType = 0; 332 | vrLen = 675; 333 | vrLoc = 872; 334 | }; 335 | 32A70AAB03705E1F00C91783 /* Test_Prefix.pch */ = { 336 | uiCtxt = { 337 | sepNavIntBoundsRect = "{{0, 0}, {619, 515}}"; 338 | sepNavSelRange = "{0, 0}"; 339 | sepNavVisRange = "{0, 150}"; 340 | }; 341 | }; 342 | 8DD76F960486AA7600D96B5E /* Test */ = { 343 | activeExec = 0; 344 | executables = ( 345 | 0A36774B0F7D287100B4662A /* Test */, 346 | ); 347 | }; 348 | } 349 | -------------------------------------------------------------------------------- /Test/Test.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A855C300F80C8F800AEAB7A /* EllipticLicense.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A3677530F7D287C00B4662A /* EllipticLicense.framework */; }; 11 | 8DD76F9A0486AA7600D96B5E /* Test.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* Test.m */; settings = {ATTRIBUTES = (); }; }; 12 | 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; 13 | 8DD76F9F0486AA7600D96B5E /* Test.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* Test.1 */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXContainerItemProxy section */ 17 | 0A3677520F7D287C00B4662A /* PBXContainerItemProxy */ = { 18 | isa = PBXContainerItemProxy; 19 | containerPortal = 0A36774E0F7D287C00B4662A /* EllipticLicense.xcodeproj */; 20 | proxyType = 2; 21 | remoteGlobalIDString = 8DC2EF5B0486A6940098B216; 22 | remoteInfo = EllipticLicense; 23 | }; 24 | 0A855C630F80CBE900AEAB7A /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 0A36774E0F7D287C00B4662A /* EllipticLicense.xcodeproj */; 27 | proxyType = 1; 28 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216 /* EllipticLicense */; 29 | remoteInfo = EllipticLicense; 30 | }; 31 | /* End PBXContainerItemProxy section */ 32 | 33 | /* Begin PBXCopyFilesBuildPhase section */ 34 | 0A3677940F7D2B3C00B4662A /* CopyFiles */ = { 35 | isa = PBXCopyFilesBuildPhase; 36 | buildActionMask = 2147483647; 37 | dstPath = ""; 38 | dstSubfolderSpec = 10; 39 | files = ( 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { 44 | isa = PBXCopyFilesBuildPhase; 45 | buildActionMask = 8; 46 | dstPath = /usr/share/man/man1/; 47 | dstSubfolderSpec = 0; 48 | files = ( 49 | 8DD76F9F0486AA7600D96B5E /* Test.1 in CopyFiles */, 50 | ); 51 | runOnlyForDeploymentPostprocessing = 1; 52 | }; 53 | /* End PBXCopyFilesBuildPhase section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 08FB7796FE84155DC02AAC07 /* Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Test.m; sourceTree = ""; }; 57 | 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 58 | 0A36774E0F7D287C00B4662A /* EllipticLicense.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = EllipticLicense.xcodeproj; path = ../Framework/EllipticLicense.xcodeproj; sourceTree = SOURCE_ROOT; }; 59 | 0A36791E0F7E489D00B4662A /* EllipticLicense.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EllipticLicense.h; path = ../EllipticLicense.h; sourceTree = SOURCE_ROOT; }; 60 | 32A70AAB03705E1F00C91783 /* Test_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Test_Prefix.pch; sourceTree = ""; }; 61 | 8DD76FA10486AA7600D96B5E /* Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Test; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | C6859EA3029092ED04C91782 /* Test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = Test.1; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | 0A855C300F80C8F800AEAB7A /* EllipticLicense.framework in Frameworks */, 71 | 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | /* End PBXFrameworksBuildPhase section */ 76 | 77 | /* Begin PBXGroup section */ 78 | 08FB7794FE84155DC02AAC07 /* Test */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 0A36774E0F7D287C00B4662A /* EllipticLicense.xcodeproj */, 82 | 08FB7795FE84155DC02AAC07 /* Source */, 83 | C6859EA2029092E104C91782 /* Documentation */, 84 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 85 | 1AB674ADFE9D54B511CA2CBB /* Products */, 86 | ); 87 | name = Test; 88 | sourceTree = ""; 89 | }; 90 | 08FB7795FE84155DC02AAC07 /* Source */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 0A36791E0F7E489D00B4662A /* EllipticLicense.h */, 94 | 32A70AAB03705E1F00C91783 /* Test_Prefix.pch */, 95 | 08FB7796FE84155DC02AAC07 /* Test.m */, 96 | ); 97 | name = Source; 98 | sourceTree = ""; 99 | }; 100 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 08FB779EFE84155DC02AAC07 /* Foundation.framework */, 104 | ); 105 | name = "External Frameworks and Libraries"; 106 | sourceTree = ""; 107 | }; 108 | 0A36774F0F7D287C00B4662A /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 0A3677530F7D287C00B4662A /* EllipticLicense.framework */, 112 | ); 113 | name = Products; 114 | sourceTree = ""; 115 | }; 116 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 8DD76FA10486AA7600D96B5E /* Test */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | C6859EA2029092E104C91782 /* Documentation */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | C6859EA3029092ED04C91782 /* Test.1 */, 128 | ); 129 | name = Documentation; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 8DD76F960486AA7600D96B5E /* Test */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "Test" */; 138 | buildPhases = ( 139 | 8DD76F990486AA7600D96B5E /* Sources */, 140 | 8DD76F9B0486AA7600D96B5E /* Frameworks */, 141 | 8DD76F9E0486AA7600D96B5E /* CopyFiles */, 142 | 0A3677940F7D2B3C00B4662A /* CopyFiles */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | 0A855C640F80CBE900AEAB7A /* PBXTargetDependency */, 148 | ); 149 | name = Test; 150 | productInstallPath = "$(HOME)/bin"; 151 | productName = Test; 152 | productReference = 8DD76FA10486AA7600D96B5E /* Test */; 153 | productType = "com.apple.product-type.tool"; 154 | }; 155 | /* End PBXNativeTarget section */ 156 | 157 | /* Begin PBXProject section */ 158 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 159 | isa = PBXProject; 160 | buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "Test" */; 161 | compatibilityVersion = "Xcode 3.1"; 162 | hasScannedForEncodings = 1; 163 | mainGroup = 08FB7794FE84155DC02AAC07 /* Test */; 164 | projectDirPath = ""; 165 | projectReferences = ( 166 | { 167 | ProductGroup = 0A36774F0F7D287C00B4662A /* Products */; 168 | ProjectRef = 0A36774E0F7D287C00B4662A /* EllipticLicense.xcodeproj */; 169 | }, 170 | ); 171 | projectRoot = ""; 172 | targets = ( 173 | 8DD76F960486AA7600D96B5E /* Test */, 174 | ); 175 | }; 176 | /* End PBXProject section */ 177 | 178 | /* Begin PBXReferenceProxy section */ 179 | 0A3677530F7D287C00B4662A /* EllipticLicense.framework */ = { 180 | isa = PBXReferenceProxy; 181 | fileType = wrapper.framework; 182 | path = EllipticLicense.framework; 183 | remoteRef = 0A3677520F7D287C00B4662A /* PBXContainerItemProxy */; 184 | sourceTree = BUILT_PRODUCTS_DIR; 185 | }; 186 | /* End PBXReferenceProxy section */ 187 | 188 | /* Begin PBXSourcesBuildPhase section */ 189 | 8DD76F990486AA7600D96B5E /* Sources */ = { 190 | isa = PBXSourcesBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | 8DD76F9A0486AA7600D96B5E /* Test.m in Sources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXSourcesBuildPhase section */ 198 | 199 | /* Begin PBXTargetDependency section */ 200 | 0A855C640F80CBE900AEAB7A /* PBXTargetDependency */ = { 201 | isa = PBXTargetDependency; 202 | name = EllipticLicense; 203 | targetProxy = 0A855C630F80CBE900AEAB7A /* PBXContainerItemProxy */; 204 | }; 205 | /* End PBXTargetDependency section */ 206 | 207 | /* Begin XCBuildConfiguration section */ 208 | 1DEB927508733DD40010E9CD /* Debug */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | ALWAYS_SEARCH_USER_PATHS = NO; 212 | COPY_PHASE_STRIP = NO; 213 | FRAMEWORK_SEARCH_PATHS = ( 214 | "$(inherited)", 215 | "\"$(SRCROOT)/../Framework/Builds/Debug\"", 216 | ); 217 | GCC_DYNAMIC_NO_PIC = NO; 218 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 219 | GCC_MODEL_TUNING = G5; 220 | GCC_OPTIMIZATION_LEVEL = 0; 221 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 222 | GCC_PREFIX_HEADER = Test_Prefix.pch; 223 | INSTALL_PATH = /usr/local/bin; 224 | PRODUCT_NAME = Test; 225 | }; 226 | name = Debug; 227 | }; 228 | 1DEB927608733DD40010E9CD /* Release */ = { 229 | isa = XCBuildConfiguration; 230 | buildSettings = { 231 | ALWAYS_SEARCH_USER_PATHS = NO; 232 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 233 | FRAMEWORK_SEARCH_PATHS = ( 234 | "$(inherited)", 235 | "\"$(SRCROOT)/../Framework/Builds/Debug\"", 236 | ); 237 | GCC_MODEL_TUNING = G5; 238 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 239 | GCC_PREFIX_HEADER = Test_Prefix.pch; 240 | INSTALL_PATH = /usr/local/bin; 241 | PRODUCT_NAME = Test; 242 | }; 243 | name = Release; 244 | }; 245 | 1DEB927908733DD40010E9CD /* Debug */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 249 | GCC_C_LANGUAGE_STANDARD = c99; 250 | GCC_OPTIMIZATION_LEVEL = 0; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | ONLY_ACTIVE_ARCH = YES; 254 | PREBINDING = NO; 255 | SDKROOT = macosx10.5; 256 | SYMROOT = ../Builds; 257 | }; 258 | name = Debug; 259 | }; 260 | 1DEB927A08733DD40010E9CD /* Release */ = { 261 | isa = XCBuildConfiguration; 262 | buildSettings = { 263 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 264 | GCC_C_LANGUAGE_STANDARD = c99; 265 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | PREBINDING = NO; 268 | SDKROOT = macosx10.5; 269 | SYMROOT = ../Builds; 270 | }; 271 | name = Release; 272 | }; 273 | /* End XCBuildConfiguration section */ 274 | 275 | /* Begin XCConfigurationList section */ 276 | 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "Test" */ = { 277 | isa = XCConfigurationList; 278 | buildConfigurations = ( 279 | 1DEB927508733DD40010E9CD /* Debug */, 280 | 1DEB927608733DD40010E9CD /* Release */, 281 | ); 282 | defaultConfigurationIsVisible = 0; 283 | defaultConfigurationName = Release; 284 | }; 285 | 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "Test" */ = { 286 | isa = XCConfigurationList; 287 | buildConfigurations = ( 288 | 1DEB927908733DD40010E9CD /* Debug */, 289 | 1DEB927A08733DD40010E9CD /* Release */, 290 | ); 291 | defaultConfigurationIsVisible = 0; 292 | defaultConfigurationName = Release; 293 | }; 294 | /* End XCConfigurationList section */ 295 | }; 296 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 297 | } 298 | -------------------------------------------------------------------------------- /Test/Test_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Test' target in the 'Test' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | --------------------------------------------------------------------------------