diff --git a/.gitignore b/.gitignore index 4e5a44ff..febefd34 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,13 @@ Icon .Trashes *.xcuserdatad +.idea + +# Eclipse files +.buildpath +.project +.settings/ + +# MACOS files +.DS_Store + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..3aeecb02 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Spec"] + path = Spec + url = https://github.com/RNCryptor/RNCryptor-Spec.git diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml deleted file mode 100644 index 43684daa..00000000 --- a/.idea/codeStyleSettings.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/.idea/dictionaries/rnapier.xml b/.idea/dictionaries/rnapier.xml deleted file mode 100644 index 10a4254e..00000000 --- a/.idea/dictionaries/rnapier.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - async - cryptor - decryptor - encryptor - hmac - rncryptor - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index e206d70d..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/master.iml b/.idea/master.iml deleted file mode 100644 index f9b36de1..00000000 --- a/.idea/master.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 9ccc125d..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - http://www.w3.org/1999/xhtml - - - - - - diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 12b24804..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b8..00000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index c80f2198..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.idea/xcode.xml b/.idea/xcode.xml deleted file mode 100644 index 685aef25..00000000 --- a/.idea/xcode.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.swift-version b/.swift-version new file mode 100644 index 00000000..9f55b2cc --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e91934ae --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: objective-c + +before_install: + - git submodule update --init --recursive + - brew update + - brew upgrade xctool + +xcode_project: RNCryptor.xcodeproj +xcode_scheme: RNCryptor +xcode_sdk: iphonesimulator7.1 + +matrix: + include: + - script: xctool -project RNCryptor.xcodeproj -scheme RNCryptor -sdk iphonesimulator7.0 build + - script: xctool -project RNCryptor.xcodeproj -scheme "RNCryptor OS X" -sdk macosx10.9 build + - script: xctool -project RNCryptor.xcodeproj -scheme "RNCryptor OS X" -sdk macosx10.10 build diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 00000000..6a1d9c06 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,43 @@ +# Version 3.0.5 + +# Clean up warnings for CocoaPods + +# Version 3.0.4 + +* Remove non-modular header from framework header #11 +* Add watchOS and tvOS support. #8 + +# Version 3.0.3 + +* Upgrade to build on Xcode 9b1 + +# Versin 3.0.2 + +* Extract to its own repository + +# Version 3.0 + +* Remove OpenSSL support. This has been moved to RNOpenSSLCryptor. +* Remove warnings on OS X 10.8 + +# Version 2.2 + +Version 2.2 is a fairly large release. It's been almost a year since 2.1 came out, and there are many small and large bug fixes. + +V2.2 updates the file format from 2 to 3. It will read format 2 files, but will only write format 3. These are not readable by RNCryptor v2.1. See Issue #77 for details. The PHP, Python, and Ruby implementations also write format 3 and read format 2 or 3. + +## Security Issues + +* Issue #91: Use constant time HMAC comparisons to avoid timing attacks +* Issue #77: KeyForPassword() broken for multi-byte passwords (UTF-8) + +## Other Noteable Changes + +* Improved PHP, Python, and Ruby implementations +* Improved test cases, with test vectors +* Issue #76: Support OSX in podspec +* Resolved static analyzer warnings +* Ensure compatibility with iOS 4.2 +* Accept settings to RNDecryptor (Issue #65) +* Copy password rather than retain it (Issue #64) +* Crash when reading v1 header diff --git a/README.md b/README.md index 9227b56e..2533aa4e 100644 --- a/README.md +++ b/README.md @@ -1,271 +1,318 @@ -# Overview +# RNCryptor -Encryptor/Decryptor for iOS +Cross-language AES Encryptor/Decryptor [data +format](https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md). -Provides an easy-to-use, Objective-C interface to the AES functionality of CommonCrypto. Simplifies correct handling of -password stretching (PBKDF2), salting, and IV. For more information on these terms, see ["Properly encrypting with AES -with CommonCrypto,"](http://robnapier.net/blog/aes-commoncrypto-564) and [iOS 6 Programming Pushing the Limits](http://iosptl.com), Chapter 15. -Also includes automatic HMAC handling to integrity-check messages. - -`RNCryptor` is an abstract class. Concrete subclasses include: - -* `RNEncryptor`, `RNDecryptor` : Writer and reader for the [RNCryptor data format](https://github.com/rnapier/RNCryptor/wiki/Data-Format). -* `RNOpenSSLEncryptor`, `RNOpenSSLDecryptor` : Writer and reader for the OpenSSL format. This format is not recommended due to its weak -security settings, but is available for compatibility. - -# Synchronous use +The primary target is Objective-C, but implementations are available in +[C++](https://github.com/RNCryptor/RNCryptor-cpp), +[C#](https://github.com/RNCryptor/RNCryptor-cs), +[Java](https://github.com/RNCryptor/JNCryptor), +[PHP](https://github.com/RNCryptor/RNCryptor-php), +[Python](https://github.com/RNCryptor/RNCryptor-python), +[Javascript](https://github.com/RNCryptor/rncryptor-js), +and [Ruby](https://github.com/RNCryptor/ruby_rncryptor). + +The data format includes all the metadata required to securely implement AES +encryption, as described in ["Properly encrypting with AES with +CommonCrypto,"](http://robnapier.net/aes-commoncrypto) and [*iOS 6 +Programming Pushing the Limits*](http://iosptl.com), Chapter 15. Specifically, +it includes: + +* AES-256 encryption +* CBC mode +* Password stretching with PBKDF2 +* Password salting +* Random IV +* Encrypt-then-hash HMAC + +## Basic Objective-C Usage The most common in-memory use case is as follows: - NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding]; - NSError *error; - NSData *encryptedData = [RNEncryptor encryptData:data - withSettings:kRNCryptorAES256Settings +``` objc +NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding]; +NSError *error; +NSData *encryptedData = [RNEncryptor encryptData:data + withSettings:kRNCryptorAES256Settings password:aPassword error:&error]; - -This generates an `NSData` including a header, encryption salt, HMAC salt, IV, ciphertext, and HMAC. To decrypt this bundle: - - NSData *decryptedData = [RNDecryptor decryptData:encryptedData - withPassword:aPassword - error:&error]; - -Note that `RNDecryptor` does not require settings. These are read from the header. - -# Asynchronous use - -`RNCryptor` suports asynchronous use, specifically designed to work with `NSURLConnection`. -This is also useful for cases where the encrypted or decrypted data will not comfortably fit in memory. -If the data will comfortably fit in memory, ansynchronous operation is best acheived using `dispatch_async()`. - -To operate in asynchronous mode, you create an `RNEncryptor` or `RNDecryptor`, providing it a handler. This handler will be -called as data is encrypted or decrypted. As data becomes available, call `addData:`. When you reach the end of the data -call `finish`. - - - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data - { - [self.cryptor addData:data]; - } - - - (void)connectionDidFinishLoading:(NSURLConnection *)connection - { - [self.cryptor finish]; - } - - // Other connection delegates - - - (void)decryptionDidFinish { - if (self.cryptor.error) { - // An error occurred. You cannot trust encryptedData at this point - } - else { - // self.encryptedData is complete. Use it as you like - } - self.encryptedData = nil; - self.cryptor = nil; - self.connection = nil; - } - - - (void)decryptRequest:(NSURLRequest *)request - { - self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; - self.cryptor = [[RNDecryptor alloc] initWithPassword:self.password - handler:^(RNCryptor *cryptor, NSData *data) { - [self.decryptedData appendData:data]; - if (cryptor.isFinished) { - [self decryptionDidFinish]; - } - }]; - } +``` + +This generates an `NSData` including a header, encryption salt, HMAC salt, IV, +ciphertext, and HMAC. To decrypt this bundle: + +``` objc +NSData *decryptedData = [RNDecryptor decryptData:encryptedData + withPassword:aPassword + error:&error]; +``` + +Note that `RNDecryptor` does not require settings. These are read from the +header. + +## Asynchronous use + +`RNCryptor suports asynchronous use, specifically designed to work with +`NSURLConnection. This is also useful for cases where the encrypted or decrypted +`data will not comfortably fit in memory. If the data will comfortably fit in +`memory, asynchronous operation is best acheived using dispatch_async(). + +To operate in asynchronous mode, you create an `RNEncryptor` or `RNDecryptor`, +providing it a handler. This handler will be called as data is encrypted or +decrypted. As data becomes available, call `addData:`. When you reach the end of +the data call `finish`. + +``` objc +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + [self.encryptedData addData:[self.cryptor addData:data]]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self.cryptor finish]; +} + +// Other connection delegates + +- (void)decryptionDidFinish { + if (self.cryptor.error) { + // An error occurred. You cannot trust encryptedData at this point + } + else { + // self.encryptedData is complete. Use it as you like + } + self.encryptedData = nil; + self.cryptor = nil; + self.connection = nil; +} + +- (void)decryptRequest:(NSURLRequest *)request { + self.encryptedData = [NSMutableData data]; + self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; + self.cryptor = [[RNDecryptor alloc] initWithPassword:self.password + handler:^(RNCryptor *cryptor, NSData *data) { + [self.decryptedData appendData:data]; + if (cryptor.isFinished) { + [self decryptionDidFinish]; + } + }]; +} +``` ## Async and Streams -When performing async operations on streams, the data can come very quickly (particularly if you're reading from a local -file). If you use RNCryptor in a naïve way, you'll queue a work blocks faster than the engine can process them and your -memory usage will spike. This is particularly true if there's only one core, such as on an iPad 1. The solution is to -only dispatch new work blocks as the previous work blocks complete. - - // Make sure that this number is larger than the header + 1 block. - // 33+16 bytes = 49 bytes. So it shouldn't be a problem. - int blockSize = 32 * 1024; - - NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:@"C++ Spec.pdf"]; - NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:@"/tmp/C++.crypt" append:NO]; - - [cryptedStream open]; - [decryptedStream open]; - - // We don't need to keep making new NSData objects. We can just use one repeatedly. - __block NSMutableData *data = [NSMutableData dataWithLength:blockSize]; - __block RNEncryptor *decryptor = nil; - - dispatch_block_t readStreamBlock = ^{ - [data setLength:blockSize]; - NSInteger bytesRead = [cryptedStream read:[data mutableBytes] maxLength:blockSize]; - if (bytesRead < 0) { - // Throw an error - } - else if (bytesRead == 0) { - [decryptor finish]; - } - else { - [data setLength:bytesRead]; - [decryptor addData:data]; - NSLog(@"Sent %ld bytes to decryptor", (unsigned long)bytesRead); - } - }; - - decryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings - password:@"blah" - handler:^(RNCryptor *cryptor, NSData *data) { - NSLog(@"Decryptor recevied %ld bytes", (unsigned long)data.length); - [decryptedStream write:data.bytes maxLength:data.length]; - if (cryptor.isFinished) { - [decryptedStream close]; - // call my delegate that I'm finished with decrypting - } - else { - // Might want to put this in a dispatch_async(), but I don't think you need it. - readStreamBlock(); - } - }]; - - // Read the first block to kick things off - readStreamBlock(); - -I'll eventually get this into the API to simplify things. See [Cyrille's SO question](http://stackoverflow.com/a/14586231/97337) -for more discussion. Pull requests welcome. - -# API Documentation - -Full API information is available at http://rnapier.github.com/RNCryptor/doc/html/Classes/RNCryptor.html. - -Details on the data format are available at https://github.com/rnapier/RNCryptor/wiki/Data-Format. - -# Building - -Comes packaged as a static library, but the source files can be dropped into any project. The OpenSSL files are not required. +When performing async operations on streams, the data can come very quickly +(particularly if you're reading from a local file). If you use RNCryptor in a +naïve way, you'll queue a work blocks faster than the engine can process them +and your memory usage will spike. This is particularly true if there's only one +core, such as on an iPad 1. The solution is to only dispatch new work blocks as +the previous work blocks complete. + +``` objc +// Make sure that this number is larger than the header + 1 block. +// 33+16 bytes = 49 bytes. So it shouldn't be a problem. +int blockSize = 32 * 1024; + +NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:@"C++ Spec.pdf"]; +NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:@"/tmp/C++.crypt" append:NO]; + +[cryptedStream open]; +[decryptedStream open]; + +// We don't need to keep making new NSData objects. We can just use one repeatedly. +__block NSMutableData *data = [NSMutableData dataWithLength:blockSize]; +__block RNEncryptor *decryptor = nil; + +dispatch_block_t readStreamBlock = ^{ + [data setLength:blockSize]; + NSInteger bytesRead = [cryptedStream read:[data mutableBytes] maxLength:blockSize]; + if (bytesRead < 0) { + // Throw an error + } + else if (bytesRead == 0) { + [decryptor finish]; + } + else { + [data setLength:bytesRead]; + [decryptor addData:data]; + NSLog(@"Sent %ld bytes to decryptor", (unsigned long)bytesRead); + } +}; + +decryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings + password:@"blah" + handler:^(RNCryptor *cryptor, NSData *data) { + NSLog(@"Decryptor recevied %ld bytes", (unsigned long)data.length); + [decryptedStream write:data.bytes maxLength:data.length]; + if (cryptor.isFinished) { + [decryptedStream close]; + // call my delegate that I'm finished with decrypting + } + else { + // Might want to put this in a dispatch_async(), but I don't think you need it. + readStreamBlock(); + } + }]; + +// Read the first block to kick things off +readStreamBlock(); +``` + +I'll eventually get this into the API to simplify things. See [Cyrille's SO +question](http://stackoverflow.com/a/14586231/97337) for more discussion. Pull +requests welcome. + +## Building + +Comes packaged as a static library, but the source files can be dropped into any +project. The OpenSSL files are not required. Requires `Security.framework`. -Supports 10.7+ and iOS 5+. For more information on backporting, read and comment on Issue #22. +Supports 10.6+ and iOS 4+. -The current file format is v2. To read v1 files (see Issue #44), you need to set the compile-time macro `RNCRYPTOR_ALLOW_V1_BAD_HMAC`. It is not possible to write v1 files anymore. +The current file format is v3. To read v1 files (see Issue #44), you need to set the compile-time macro `RNCRYPTOR_ALLOW_V1_BAD_HMAC`. It is not possible to write v1 files anymore. -# Design considerations +## Design considerations `RNCryptor` has several design goals, in order of importance: -## Easy to use correctly for most common use cases +### Easy to use correctly for most common use cases The most critical concern is that it be easy for non-experts to use `RNCryptor` correctly. A framework that is more secure, but requires a steep learning curve on the developer will either be not used, or used incorrectly. Whenever possible, a single line of code should "do the right thing" for the most common cases. This also requires that it fail correctly and provide good errors. -## Reliance on CommonCryptor functionality +### Reliance on CommonCryptor functionality `RNCryptor` has very little "security" code. It relies as much as possible on the OS-provided CommonCryptor. If a feature does not exist in CommonCryptor, then it generally will not be provided in `RNCryptor`. -## Best practice security - -Wherever possible within the above constraints, the best available algorithms are applied. This means AES-256, HMAC+SHA1, and PBKDF2: - -* AES-256. While Bruce Schneier has made some interesting recommendations regarding moving to AES-128 due to certain attacks on AES-256, my current thinking is in line with Colin Percival here: http://www.daemonology.net/blog/2009-07-31-thoughts-on-AES.html. PBKDF2 output is effectively random, which should negate related-keys attacks against the kinds of use cases we're interested in. - -* AES-CBC mode. This was a somewhat complex decision, but the ubiquity of CBC outweighs other considerations here. There are no -major problems with CBC mode, and nonce-based modes like CTR have other trade-offs. See http://robnapier.net/blog/mode-rncryptor-767 for -more details on this decision. - -* Encrypt-then-MAC. If there were a good authenticated AES mode on iOS (GCM for instance), I would probably use that for -its simplicity. Colin Percival makes [good arguments for hand-coding an encrypt-than-MAC](http://www.daemonology.net/blog/2009-06-24-encrypt-then-mac.html) rather than using an authenticated -AES mode, but in RNCryptor mananging the HMAC actually adds quite a bit of complexity. I'd rather the complexity at a -more broadly peer-reviewed layer like CommonCryptor than at the RNCryptor layer. But this isn't an option, so I fall back -to my own Encrypt-than-MAC. +### Best practice security + +Wherever possible within the above constraints, the best available algorithms +are applied. This means AES-256, HMAC+SHA1, and PBKDF2: + +* AES-256. While Bruce Schneier has made some interesting recommendations +regarding moving to AES-128 due to certain attacks on AES-256, my current +thinking is in line with [Colin +Percival](http://www.daemonology.net/blog/2009-07-31-thoughts-on-AES.html). +PBKDF2 output is effectively random, which should negate related-keys attacks +against the kinds of use cases we're interested in. + +* AES-CBC mode. This was a somewhat complex decision, but the ubiquity of CBC +outweighs other considerations here. There are no major problems with CBC mode, +and nonce-based modes like CTR have other trade-offs. See ["Mode changes for +RNCryptor"](http://robnapier.net/blog/mode-rncryptor) for more details on this +decision. + +* Encrypt-then-MAC. If there were a good authenticated AES mode on iOS (GCM for +instance), I would probably use that for its simplicity. Colin Percival makes +[good arguments for hand-coding an encrypt-than- +MAC](http://www.daemonology.net/blog/2009-06-24-encrypt-then-mac.html) rather +than using an authenticated AES mode, but in RNCryptor mananging the HMAC +actually adds quite a bit of complexity. I'd rather the complexity at a more +broadly peer-reviewed layer like CommonCryptor than at the RNCryptor layer. But +this isn't an option, so I fall back to my own Encrypt-than-MAC. * HMAC+SHA256. No surprises here. -* PBKDF2. While bcrypt and scrypt may be more secure than PBKDF2, CommonCryptor only supports PBKDF2. NIST also continues to recommend PBKDF2. http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage We use 10k rounds of PBKDF2 which represents about 80ms on an iPhone 4. +* PBKDF2. While bcrypt and scrypt may be more secure than PBKDF2, CommonCryptor +only supports PBKDF2. [NIST also continues to recommend +PBKDF2](http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage). We use 10k rounds of PBKDF2 +which represents about 80ms on an iPhone 4. -## Code simplicity +### Code simplicity -`RNCryptor` endeavors to be implemented as simply as possible, avoiding tricky code. It is designed to be easy to read and code review. +`RNCryptor endeavors to be implemented as simply as possible, avoiding tricky +`code. It is designed to be easy to read and code review. -## Performance +### Performance -Performance is a goal, but not the most important goal. The code must be secure and easy to use. Within that, it is as fast and memory-efficient as possible. +Performance is a goal, but not the most important goal. The code must be secure +and easy to use. Within that, it is as fast and memory-efficient as possible. -## Portability +### Portability -Without sacrificing other goals, it is preferable to read the output format of `RNCryptor` on other platforms. +Without sacrificing other goals, it is preferable to read the output format of +`RNCryptor` on other platforms. -# Roadmap +## Version History +* v2.2 Switches to file format v3 to deal with Issue #77. * v2.1 Switches to file format v2 to deal with Issue #44. * v2.0 adds asynchronous modes. * v2.1 backports `RNCryptor` to older versions of Mac OS X (and possibly iOS). -# LICENSE -Except where otherwise indicated in the source code, this code is licensed under the MIT License: - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - -Portions of this code, indicated in the source, are licensed under the following license: - - /*- - * Copyright (c) 2008 Damien Bergamini - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -Portions of ths code, indicated in the source, are licensed under the APSL license: - - /* - * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ +## LICENSE + +Except where otherwise indicated in the source code, this code is licensed under +the MIT License: + +``` +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +``` + +Portions of this code, indicated in the source, are licensed under the following +license: + +``` +/*- + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +``` + +Portions of this code, indicated in the source, are licensed under the APSL +license: + +``` +/* + * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +``` diff --git a/RNCryptor iOS/Info.plist b/RNCryptor iOS/Info.plist new file mode 100644 index 00000000..d3de8eef --- /dev/null +++ b/RNCryptor iOS/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/RNCryptor iOS/RNCryptor iOS.h b/RNCryptor iOS/RNCryptor iOS.h new file mode 100644 index 00000000..207e0649 --- /dev/null +++ b/RNCryptor iOS/RNCryptor iOS.h @@ -0,0 +1,22 @@ +// +// RNCryptor iOS.h +// RNCryptor iOS +// +// Created by Daniel Brooks on 5/25/15. +// Copyright (c) 2015 Rob Napier. All rights reserved. +// + +#import + +//! Project version number for RNCryptor iOS. +FOUNDATION_EXPORT double RNCryptor_iOSVersionNumber; + +//! Project version string for RNCryptor iOS. +FOUNDATION_EXPORT const unsigned char RNCryptor_iOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import +#import + diff --git a/RNCryptor iOS/module.modulemap b/RNCryptor iOS/module.modulemap new file mode 100644 index 00000000..e827da9c --- /dev/null +++ b/RNCryptor iOS/module.modulemap @@ -0,0 +1,6 @@ +framework module RNCryptor { + umbrella header "RNCryptor iOS.h" + + export * + module * { export * } +} diff --git a/RNCryptor tvOS/Info.plist b/RNCryptor tvOS/Info.plist new file mode 100644 index 00000000..fbe1e6b3 --- /dev/null +++ b/RNCryptor tvOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/RNCryptor tvOS/RNCryptor tvOS.h b/RNCryptor tvOS/RNCryptor tvOS.h new file mode 100644 index 00000000..9ad0f34a --- /dev/null +++ b/RNCryptor tvOS/RNCryptor tvOS.h @@ -0,0 +1,22 @@ +// +// RNCryptor tvOS.h +// RNCryptor tvOS +// +// Created by Jeff Kelley on 11/15/16. +// Copyright © 2016 Rob Napier. All rights reserved. +// + +#import + +//! Project version number for RNCryptor tvOS. +FOUNDATION_EXPORT double RNCryptor_tvOSVersionNumber; + +//! Project version string for RNCryptor tvOS. +FOUNDATION_EXPORT const unsigned char RNCryptor_tvOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import +#import + diff --git a/RNCryptor watchOS/Info.plist b/RNCryptor watchOS/Info.plist new file mode 100644 index 00000000..fbe1e6b3 --- /dev/null +++ b/RNCryptor watchOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/RNCryptor watchOS/RNCryptor watchOS.h b/RNCryptor watchOS/RNCryptor watchOS.h new file mode 100644 index 00000000..760965c0 --- /dev/null +++ b/RNCryptor watchOS/RNCryptor watchOS.h @@ -0,0 +1,22 @@ +// +// RNCryptor watchOS.h +// RNCryptor watchOS +// +// Created by Jeff Kelley on 11/15/16. +// Copyright © 2016 Rob Napier. All rights reserved. +// + +#import + +//! Project version number for RNCryptor watchOS. +FOUNDATION_EXPORT double RNCryptor_watchOSVersionNumber; + +//! Project version string for RNCryptor watchOS. +FOUNDATION_EXPORT const unsigned char RNCryptor_watchOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import +#import + diff --git a/RNCryptor.podspec b/RNCryptor-objc.podspec similarity index 79% rename from RNCryptor.podspec rename to RNCryptor-objc.podspec index 3b077283..51d7bce2 100644 --- a/RNCryptor.podspec +++ b/RNCryptor-objc.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| - s.name = 'RNCryptor' - s.version = '2.1' + s.name = 'RNCryptor-objc' + s.version = '3.0.5' s.summary = 'Encryptor/Decryptor for iOS.' s.authors = {'Rob Napier' => 'robnapier@gmail.com'} s.license = { @@ -15,16 +15,17 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. LIC } - s.source = { :git => 'https://github.com/rnapier/RNCryptor.git', :tag => 'RNCryptor-2.0'} + s.source = { :git => 'https://github.com/RNCryptor/RNCryptor-objc.git', :tag => "RNCryptor-#{s.version.to_s}" } s.description = 'Provides an easy-to-use, Objective-C interface to the AES functionality of CommonCrypto. Simplifies correct handling of password stretching (PBKDF2), salting, and IV.' s.homepage = 'https://github.com/rnapier/RNCryptor' s.source_files = 'RNCryptor/*.{h,m}' s.public_header_files = 'RNCryptor/*.h' + s.private_header_files = "RNCryptor/RNCryptorEngine.h", "RNCryptor/RNCryptor+Private.h" s.requires_arc = true - s.ios.frameworks = 'Security' -# OS X building is broken in 2.0. - s.platform = :ios, '5.0' -# Comment the above and uncomment below to support OS X and iOS. -# s.ios.deployment_target = '5.0' -# s.osx.deployment_target = '10.7' + s.frameworks = 'Security' + s.ios.deployment_target = '5.0' + s.osx.deployment_target = '10.7' + s.watchos.deployment_target = '2.0' + s.tvos.deployment_target = '9.0' end + diff --git a/RNCryptor.xcodeproj/project.pbxproj b/RNCryptor.xcodeproj/project.pbxproj index 98ce61a7..ae455c02 100644 --- a/RNCryptor.xcodeproj/project.pbxproj +++ b/RNCryptor.xcodeproj/project.pbxproj @@ -3,62 +3,82 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 47; objects = { /* Begin PBXBuildFile section */ - 90CAAF5A1737E408005C53B2 /* RNCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90CAAF5B1737E408005C53B2 /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90CAAF5C1737E408005C53B2 /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90CAAF5D1737E408005C53B2 /* RNOpenSSLCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B806E /* RNOpenSSLCryptor.h */; }; - 90CAAF5E1737E408005C53B2 /* RNOpenSSLDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808E /* RNOpenSSLDecryptor.h */; }; - 90CAAF5F1737E408005C53B2 /* RNOpenSSLEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808C /* RNOpenSSLEncryptor.h */; }; - 90CAAF601737E408005C53B2 /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; }; - 90CAAF611737E408005C53B2 /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; }; - 90DE45221721AFF600B153AF /* RNCryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; }; - 90DE45231721AFF600B153AF /* RNDecryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; }; - 90DE45241721AFF600B153AF /* RNEncryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; }; - 90DE45251721AFF600B153AF /* RNOpenSSLCryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B806E /* RNOpenSSLCryptor.h */; }; - 90DE45261721AFF600B153AF /* RNOpenSSLDecryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808E /* RNOpenSSLDecryptor.h */; }; - 90DE45271721AFF600B153AF /* RNOpenSSLEncryptor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808C /* RNOpenSSLEncryptor.h */; }; - 90DE45281721AFF600B153AF /* RNCryptorEngine.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; }; - 90DE45291721AFF600B153AF /* RNCryptor+Private.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; }; + 1F3717571DDB9C60009E537B /* RNCryptor watchOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3717551DDB9C60009E537B /* RNCryptor watchOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F37175C1DDB9CB0009E537B /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; + 1F37175D1DDB9CB0009E537B /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; + 1F37175E1DDB9CB0009E537B /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; + 1F37175F1DDB9CB0009E537B /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; + 1F3717601DDB9CB7009E537B /* RNCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717611DDB9CBC009E537B /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717621DDB9CC3009E537B /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717631DDB9CC9009E537B /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1F3717641DDB9CCE009E537B /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1F37176E1DDB9D1B009E537B /* RNCryptor tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F37176C1DDB9D1B009E537B /* RNCryptor tvOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717731DDB9D4C009E537B /* RNCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717741DDB9D50009E537B /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; + 1F3717751DDB9D52009E537B /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717761DDB9D56009E537B /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; + 1F3717771DDB9D59009E537B /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F3717781DDB9D5D009E537B /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; + 1F3717791DDB9D60009E537B /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1F37177A1DDB9D63009E537B /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; + 1F37177B1DDB9D66009E537B /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1F37177D1DDB9DF9009E537B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F37177C1DDB9DF9009E537B /* Foundation.framework */; }; + 1F37177F1DDB9DFD009E537B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F37177E1DDB9DFD009E537B /* Security.framework */; }; + 1F3717811DDB9E07009E537B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F3717801DDB9E07009E537B /* Foundation.framework */; }; + 1F3717831DDB9E0A009E537B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F3717821DDB9E0A009E537B /* Security.framework */; }; + 4ABDC61718615875000DE03F /* RNCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4ABDC61918615894000DE03F /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4ABDC61C18615894000DE03F /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4ABDC61D186158B2000DE03F /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4ABDC61E186158B2000DE03F /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 659134EE1B14262C00B82A96 /* RNCryptor iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 659134ED1B14262C00B82A96 /* RNCryptor iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 659135021B14265A00B82A96 /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; + 659135031B14265A00B82A96 /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; + 659135041B14265A00B82A96 /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; + 659135051B14265A00B82A96 /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; + 659135061B14266100B82A96 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7565221512D9A8007B806B /* Security.framework */; }; + 659135071B14266700B82A96 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F31512D3C4007B806B /* Foundation.framework */; }; + 659135081B14268500B82A96 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB13428415E0FC2300456914 /* InfoPlist.strings */; }; + 659135091B14271500B82A96 /* RNCryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB75651A1512D3E9007B806B /* RNCryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6591350A1B14271500B82A96 /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6591350B1B14271500B82A96 /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6591350C1B14271500B82A96 /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6591350D1B14271500B82A96 /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; AB13428615E0FC2300456914 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB13428415E0FC2300456914 /* InfoPlist.strings */; }; - AB13428F15E0FC4600456914 /* RNOpenSSLDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8090 /* RNOpenSSLDecryptor.m */; }; - AB13429015E0FC4600456914 /* RNOpenSSLEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808A /* RNOpenSSLEncryptor.m */; }; AB13429115E0FC4600456914 /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; AB13429215E0FC4600456914 /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; AB13429315E0FC4600456914 /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; - AB13429415E0FC4600456914 /* RNOpenSSLCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B806C /* RNOpenSSLCryptor.m */; }; AB13429515E0FC4600456914 /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; - AB13429715E0FC4E00456914 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB13429615E0FC4E00456914 /* Security.framework */; }; - AB13429915E0FD1D00456914 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB13429815E0FD1D00456914 /* Foundation.framework */; }; + FB30216118802ED900BF8F3C /* RNCryptorGeneratedVectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB30216018802ED900BF8F3C /* RNCryptorGeneratedVectorTests.m */; }; + FB53C196187F6AB300952674 /* XCTestCase+RNCryptorVectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB53C195187F6AB300952674 /* XCTestCase+RNCryptorVectorTests.m */; }; FB6AC68D16F6704200CA0C0A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F31512D3C4007B806B /* Foundation.framework */; }; FB6AC69016F6704200CA0C0A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FB6AC68F16F6704200CA0C0A /* main.m */; }; FB6AC69D16F672F700CA0C0A /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; FB6AC69E16F672F700CA0C0A /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; FB6AC69F16F672F700CA0C0A /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; FB6AC6A016F672F700CA0C0A /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; - FB6AC6A116F6730100CA0C0A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB13429615E0FC4E00456914 /* Security.framework */; }; - FB6CB6D7158FD093001F6D61 /* test.enc in Resources */ = {isa = PBXBuildFile; fileRef = FB6CB6D6158FD093001F6D61 /* test.enc */; }; + FB6C961B185A0F7600CC2098 /* RNCryptorTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = FB6C961A185A0F7600CC2098 /* RNCryptorTestHelpers.m */; }; + FB6CB6D7158FD093001F6D61 /* openssl.enc in Resources */ = {isa = PBXBuildFile; fileRef = FB6CB6D6158FD093001F6D61 /* openssl.enc */; }; FB7564F41512D3C4007B806B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F31512D3C4007B806B /* Foundation.framework */; }; - FB7565021512D3C4007B806B /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7565011512D3C4007B806B /* SenTestingKit.framework */; }; FB7565051512D3C4007B806B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F31512D3C4007B806B /* Foundation.framework */; }; FB7565081512D3C4007B806B /* libRNCryptor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F01512D3C4007B806B /* libRNCryptor.a */; }; FB75650E1512D3C4007B806B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FB75650C1512D3C4007B806B /* InfoPlist.strings */; }; FB7565111512D3C5007B806B /* RNCryptorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565101512D3C5007B806B /* RNCryptorTests.m */; }; FB75651D1512D3E9007B806B /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB75651B1512D3E9007B806B /* RNCryptor.m */; }; FB7565241512D9BE007B806B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7565221512D9A8007B806B /* Security.framework */; }; - FB7565241512D9BE007B806D /* RNOpenSSLCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B806C /* RNOpenSSLCryptor.m */; }; FB7565241512D9BE007B8075 /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8074 /* RNEncryptor.m */; }; + FB7565241512D9BE007B8077 /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8076 /* RNEncryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; FB7565241512D9BE007B8079 /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8078 /* RNDecryptor.m */; }; + FB7565241512D9BE007B807B /* RNDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807A /* RNDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; FB7565241512D9BE007B807D /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807C /* RNCryptorEngine.m */; }; - FB7565241512D9BE007B808B /* RNOpenSSLEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B808A /* RNOpenSSLEncryptor.m */; }; - FB7565241512D9BE007B8091 /* RNOpenSSLDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8090 /* RNOpenSSLDecryptor.m */; }; - FBE1F73B16A899E400C90463 /* RNCryptorV1.enc in CopyFiles */ = {isa = PBXBuildFile; fileRef = FBE1F73A16A899D800C90463 /* RNCryptorV1.enc */; }; - FBF7D58E167E5031004B6F0F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7564F31512D3C4007B806B /* Foundation.framework */; }; - FBF7D591167E5032004B6F0F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FBF7D590167E5032004B6F0F /* main.m */; }; - FBF7D5A9167E515D004B6F0F /* RNCryptor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB13427A15E0FC2300456914 /* RNCryptor.framework */; }; + FB7565241512D9BE007B807F /* RNCryptorEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B807E /* RNCryptorEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; + FB7565241512D9BE007B8085 /* RNCryptor+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7565241512D9BE007B8084 /* RNCryptor+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + FBE8BC9E1D9072970070C8D0 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBE8BC9D1D9072970070C8D0 /* Security.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -90,27 +110,31 @@ runOnlyForDeploymentPostprocessing = 0; }; FB6AC68A16F6704100CA0C0A /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; - FBF7D58A167E5031004B6F0F /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 12; dstPath = ""; dstSubfolderSpec = 16; files = ( - FBE1F73B16A899E400C90463 /* RNCryptorV1.enc in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1F3717531DDB9C5F009E537B /* RNCryptor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNCryptor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F3717551DDB9C60009E537B /* RNCryptor watchOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCryptor watchOS.h"; sourceTree = ""; }; + 1F3717561DDB9C60009E537B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1F37176A1DDB9D1B009E537B /* RNCryptor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNCryptor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F37176C1DDB9D1B009E537B /* RNCryptor tvOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCryptor tvOS.h"; sourceTree = ""; }; + 1F37176D1DDB9D1B009E537B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1F37177C1DDB9DF9009E537B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 1F37177E1DDB9DFD009E537B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 1F3717801DDB9E07009E537B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 1F3717821DDB9E0A009E537B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 659134E91B14262B00B82A96 /* RNCryptor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNCryptor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 659134EC1B14262C00B82A96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 659134ED1B14262C00B82A96 /* RNCryptor iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCryptor iOS.h"; sourceTree = ""; }; + 659135141B142E6A00B82A96 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; AB13427A15E0FC2300456914 /* RNCryptor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNCryptor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AB13427E15E0FC2300456914 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; AB13427F15E0FC2300456914 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; @@ -118,51 +142,69 @@ AB13428315E0FC2300456914 /* RNCryptorOSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RNCryptorOSX-Info.plist"; path = "../RNCryptorOSX/RNCryptorOSX-Info.plist"; sourceTree = ""; }; AB13428515E0FC2300456914 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; AB13428715E0FC2300456914 /* RNCryptorOSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "RNCryptorOSX-Prefix.pch"; path = "../RNCryptorOSX/RNCryptorOSX-Prefix.pch"; sourceTree = ""; }; - AB13429615E0FC4E00456914 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; - AB13429815E0FD1D00456914 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + FB30216018802ED900BF8F3C /* RNCryptorGeneratedVectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCryptorGeneratedVectorTests.m; sourceTree = ""; }; + FB53C195187F6AB300952674 /* XCTestCase+RNCryptorVectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCTestCase+RNCryptorVectorTests.m"; sourceTree = ""; }; + FB53C197187F6C6500952674 /* XCTestCase+RNCryptorVectorTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCTestCase+RNCryptorVectorTests.h"; sourceTree = ""; }; FB6AC68C16F6704100CA0C0A /* rncrypt */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = rncrypt; sourceTree = BUILT_PRODUCTS_DIR; }; FB6AC68F16F6704200CA0C0A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; FB6AC69216F6704200CA0C0A /* rncrypt-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "rncrypt-Prefix.pch"; sourceTree = ""; }; - FB6CB6D6158FD093001F6D61 /* test.enc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.enc; sourceTree = ""; }; + FB6C9619185A0F7600CC2098 /* RNCryptorTestHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCryptorTestHelpers.h; sourceTree = ""; }; + FB6C961A185A0F7600CC2098 /* RNCryptorTestHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCryptorTestHelpers.m; sourceTree = ""; }; + FB6CB6D6158FD093001F6D61 /* openssl.enc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = openssl.enc; sourceTree = ""; }; FB7564F01512D3C4007B806B /* libRNCryptor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCryptor.a; sourceTree = BUILT_PRODUCTS_DIR; }; FB7564F31512D3C4007B806B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; FB7564F71512D3C4007B806B /* RNCryptor-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCryptor-Prefix.pch"; sourceTree = ""; }; - FB7565001512D3C4007B806B /* RNCryptorTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNCryptorTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; - FB7565011512D3C4007B806B /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; + FB7565001512D3C4007B806B /* RNCryptorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNCryptorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; FB75650B1512D3C4007B806B /* RNCryptorTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RNCryptorTests-Info.plist"; sourceTree = ""; }; FB75650D1512D3C4007B806B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - FB75650F1512D3C4007B806B /* RNCryptorTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNCryptorTests.h; sourceTree = ""; }; FB7565101512D3C5007B806B /* RNCryptorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCryptorTests.m; sourceTree = ""; }; - FB75651A1512D3E9007B806B /* RNCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCryptor.h; sourceTree = ""; }; + FB75651A1512D3E9007B806B /* RNCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = RNCryptor.h; sourceTree = ""; tabWidth = 2; }; FB75651B1512D3E9007B806B /* RNCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCryptor.m; sourceTree = ""; }; FB7565221512D9A8007B806B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - FB7565241512D9BE007B806C /* RNOpenSSLCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNOpenSSLCryptor.m; sourceTree = ""; }; - FB7565241512D9BE007B806E /* RNOpenSSLCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNOpenSSLCryptor.h; sourceTree = ""; }; - FB7565241512D9BE007B8074 /* RNEncryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNEncryptor.m; sourceTree = ""; }; + FB7565241512D9BE007B8074 /* RNEncryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RNEncryptor.m; sourceTree = ""; tabWidth = 2; }; FB7565241512D9BE007B8076 /* RNEncryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNEncryptor.h; sourceTree = ""; }; FB7565241512D9BE007B8078 /* RNDecryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNDecryptor.m; sourceTree = ""; }; FB7565241512D9BE007B807A /* RNDecryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNDecryptor.h; sourceTree = ""; }; - FB7565241512D9BE007B807C /* RNCryptorEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCryptorEngine.m; sourceTree = ""; }; + FB7565241512D9BE007B807C /* RNCryptorEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RNCryptorEngine.m; sourceTree = ""; tabWidth = 2; }; FB7565241512D9BE007B807E /* RNCryptorEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCryptorEngine.h; sourceTree = ""; }; FB7565241512D9BE007B8084 /* RNCryptor+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RNCryptor+Private.h"; sourceTree = ""; }; - FB7565241512D9BE007B808A /* RNOpenSSLEncryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNOpenSSLEncryptor.m; sourceTree = ""; }; - FB7565241512D9BE007B808C /* RNOpenSSLEncryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNOpenSSLEncryptor.h; sourceTree = ""; }; - FB7565241512D9BE007B808E /* RNOpenSSLDecryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNOpenSSLDecryptor.h; sourceTree = ""; }; - FB7565241512D9BE007B8090 /* RNOpenSSLDecryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNOpenSSLDecryptor.m; sourceTree = ""; }; FB7565241512D9BE007B8092 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = file.md; path = README.md; sourceTree = ""; }; - FBE1F73A16A899D800C90463 /* RNCryptorV1.enc */ = {isa = PBXFileReference; lastKnownFileType = file; path = RNCryptorV1.enc; sourceTree = SOURCE_ROOT; }; - FBF7D58C167E5031004B6F0F /* RNCryptorVectors */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = RNCryptorVectors; sourceTree = BUILT_PRODUCTS_DIR; }; - FBF7D590167E5032004B6F0F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - FBF7D593167E5032004B6F0F /* RNCryptorVectors-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCryptorVectors-Prefix.pch"; sourceTree = ""; }; + FBE8BC9D1D9072970070C8D0 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 1F37174F1DDB9C5F009E537B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F37177D1DDB9DF9009E537B /* Foundation.framework in Frameworks */, + 1F37177F1DDB9DFD009E537B /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F3717661DDB9D1B009E537B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F3717811DDB9E07009E537B /* Foundation.framework in Frameworks */, + 1F3717831DDB9E0A009E537B /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 659134E51B14262B00B82A96 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 659135071B14266700B82A96 /* Foundation.framework in Frameworks */, + 659135061B14266100B82A96 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AB13427615E0FC2300456914 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - AB13429915E0FD1D00456914 /* Foundation.framework in Frameworks */, - AB13429715E0FC4E00456914 /* Security.framework in Frameworks */, + FBE8BC9E1D9072970070C8D0 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -170,7 +212,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FB6AC6A116F6730100CA0C0A /* Security.framework in Frameworks */, FB6AC68D16F6704200CA0C0A /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -187,25 +228,67 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FB7565021512D3C4007B806B /* SenTestingKit.framework in Frameworks */, FB7565051512D3C4007B806B /* Foundation.framework in Frameworks */, FB7565081512D3C4007B806B /* libRNCryptor.a in Frameworks */, FB7565241512D9BE007B806B /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - FBF7D589167E5031004B6F0F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FBF7D5A9167E515D004B6F0F /* RNCryptor.framework in Frameworks */, - FBF7D58E167E5031004B6F0F /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1F3717541DDB9C60009E537B /* RNCryptor watchOS */ = { + isa = PBXGroup; + children = ( + 1F3717551DDB9C60009E537B /* RNCryptor watchOS.h */, + 1F37175B1DDB9C8A009E537B /* Supporting Files */, + ); + path = "RNCryptor watchOS"; + sourceTree = ""; + }; + 1F37175B1DDB9C8A009E537B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 1F3717561DDB9C60009E537B /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1F37176B1DDB9D1B009E537B /* RNCryptor tvOS */ = { + isa = PBXGroup; + children = ( + 1F37176C1DDB9D1B009E537B /* RNCryptor tvOS.h */, + 1F3717721DDB9D26009E537B /* Supporting Files */, + ); + path = "RNCryptor tvOS"; + sourceTree = ""; + }; + 1F3717721DDB9D26009E537B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 1F37176D1DDB9D1B009E537B /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 659134EA1B14262C00B82A96 /* RNCryptor iOS */ = { + isa = PBXGroup; + children = ( + 659134ED1B14262C00B82A96 /* RNCryptor iOS.h */, + 659134EB1B14262C00B82A96 /* Supporting Files */, + 659135141B142E6A00B82A96 /* module.modulemap */, + ); + path = "RNCryptor iOS"; + sourceTree = ""; + }; + 659134EB1B14262C00B82A96 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 659134EC1B14262C00B82A96 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; AB13427D15E0FC2300456914 /* Other Frameworks */ = { isa = PBXGroup; children = ( @@ -234,6 +317,14 @@ name = "Supporting Files"; sourceTree = ""; }; + FB30215F18802E9700BF8F3C /* Generated */ = { + isa = PBXGroup; + children = ( + FB30216018802ED900BF8F3C /* RNCryptorGeneratedVectorTests.m */, + ); + path = Generated; + sourceTree = ""; + }; FB6AC68E16F6704200CA0C0A /* rncrypt */ = { isa = PBXGroup; children = ( @@ -254,27 +345,31 @@ FB7564E51512D3C4007B806B = { isa = PBXGroup; children = ( - AB13429815E0FD1D00456914 /* Foundation.framework */, - AB13429615E0FC4E00456914 /* Security.framework */, FB7565241512D9BE007B8092 /* README.md */, FB7564F51512D3C4007B806B /* RNCryptor */, FB7565091512D3C4007B806B /* RNCryptorTests */, AB13428115E0FC2300456914 /* RNCryptorOSX */, - FBF7D58F167E5031004B6F0F /* RNCryptorVectors */, FB6AC68E16F6704200CA0C0A /* rncrypt */, + 659134EA1B14262C00B82A96 /* RNCryptor iOS */, + 1F3717541DDB9C60009E537B /* RNCryptor watchOS */, + 1F37176B1DDB9D1B009E537B /* RNCryptor tvOS */, FB7564F21512D3C4007B806B /* Frameworks */, FB7564F11512D3C4007B806B /* Products */, ); + indentWidth = 2; sourceTree = ""; + tabWidth = 2; }; FB7564F11512D3C4007B806B /* Products */ = { isa = PBXGroup; children = ( FB7564F01512D3C4007B806B /* libRNCryptor.a */, - FB7565001512D3C4007B806B /* RNCryptorTests.octest */, + FB7565001512D3C4007B806B /* RNCryptorTests.xctest */, AB13427A15E0FC2300456914 /* RNCryptor.framework */, - FBF7D58C167E5031004B6F0F /* RNCryptorVectors */, FB6AC68C16F6704100CA0C0A /* rncrypt */, + 659134E91B14262B00B82A96 /* RNCryptor.framework */, + 1F3717531DDB9C5F009E537B /* RNCryptor.framework */, + 1F37176A1DDB9D1B009E537B /* RNCryptor.framework */, ); name = Products; sourceTree = ""; @@ -282,9 +377,13 @@ FB7564F21512D3C4007B806B /* Frameworks */ = { isa = PBXGroup; children = ( + 1F3717821DDB9E0A009E537B /* Security.framework */, + 1F3717801DDB9E07009E537B /* Foundation.framework */, + 1F37177E1DDB9DFD009E537B /* Security.framework */, + 1F37177C1DDB9DF9009E537B /* Foundation.framework */, + FBE8BC9D1D9072970070C8D0 /* Security.framework */, FB7565221512D9A8007B806B /* Security.framework */, FB7564F31512D3C4007B806B /* Foundation.framework */, - FB7565011512D3C4007B806B /* SenTestingKit.framework */, AB13427D15E0FC2300456914 /* Other Frameworks */, ); name = Frameworks; @@ -299,12 +398,6 @@ FB7565241512D9BE007B8078 /* RNDecryptor.m */, FB7565241512D9BE007B8076 /* RNEncryptor.h */, FB7565241512D9BE007B8074 /* RNEncryptor.m */, - FB7565241512D9BE007B806E /* RNOpenSSLCryptor.h */, - FB7565241512D9BE007B806C /* RNOpenSSLCryptor.m */, - FB7565241512D9BE007B8090 /* RNOpenSSLDecryptor.m */, - FB7565241512D9BE007B808E /* RNOpenSSLDecryptor.h */, - FB7565241512D9BE007B808C /* RNOpenSSLEncryptor.h */, - FB7565241512D9BE007B808A /* RNOpenSSLEncryptor.m */, FB7565241512D9BE007B807E /* RNCryptorEngine.h */, FB7565241512D9BE007B807C /* RNCryptorEngine.m */, FB7565241512D9BE007B8084 /* RNCryptor+Private.h */, @@ -324,8 +417,12 @@ FB7565091512D3C4007B806B /* RNCryptorTests */ = { isa = PBXGroup; children = ( - FB75650F1512D3C4007B806B /* RNCryptorTests.h */, + FB30215F18802E9700BF8F3C /* Generated */, + FB53C197187F6C6500952674 /* XCTestCase+RNCryptorVectorTests.h */, + FB53C195187F6AB300952674 /* XCTestCase+RNCryptorVectorTests.m */, FB7565101512D3C5007B806B /* RNCryptorTests.m */, + FB6C9619185A0F7600CC2098 /* RNCryptorTestHelpers.h */, + FB6C961A185A0F7600CC2098 /* RNCryptorTestHelpers.m */, FB75650A1512D3C4007B806B /* Supporting Files */, ); path = RNCryptorTests; @@ -334,52 +431,136 @@ FB75650A1512D3C4007B806B /* Supporting Files */ = { isa = PBXGroup; children = ( - FB6CB6D6158FD093001F6D61 /* test.enc */, + FB6CB6D6158FD093001F6D61 /* openssl.enc */, FB75650B1512D3C4007B806B /* RNCryptorTests-Info.plist */, FB75650C1512D3C4007B806B /* InfoPlist.strings */, ); name = "Supporting Files"; sourceTree = ""; }; - FBF7D58F167E5031004B6F0F /* RNCryptorVectors */ = { - isa = PBXGroup; - children = ( - FBF7D590167E5032004B6F0F /* main.m */, - FBE1F73A16A899D800C90463 /* RNCryptorV1.enc */, - FBF7D592167E5032004B6F0F /* Supporting Files */, +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 1F3717501DDB9C5F009E537B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F3717601DDB9CB7009E537B /* RNCryptor.h in Headers */, + 1F3717621DDB9CC3009E537B /* RNEncryptor.h in Headers */, + 1F3717641DDB9CCE009E537B /* RNCryptor+Private.h in Headers */, + 1F3717611DDB9CBC009E537B /* RNDecryptor.h in Headers */, + 1F3717631DDB9CC9009E537B /* RNCryptorEngine.h in Headers */, + 1F3717571DDB9C60009E537B /* RNCryptor watchOS.h in Headers */, ); - path = RNCryptorVectors; - sourceTree = ""; + runOnlyForDeploymentPostprocessing = 0; }; - FBF7D592167E5032004B6F0F /* Supporting Files */ = { - isa = PBXGroup; - children = ( - FBF7D593167E5032004B6F0F /* RNCryptorVectors-Prefix.pch */, + 1F3717671DDB9D1B009E537B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F3717731DDB9D4C009E537B /* RNCryptor.h in Headers */, + 1F3717771DDB9D59009E537B /* RNEncryptor.h in Headers */, + 1F37177B1DDB9D66009E537B /* RNCryptor+Private.h in Headers */, + 1F3717751DDB9D52009E537B /* RNDecryptor.h in Headers */, + 1F3717791DDB9D60009E537B /* RNCryptorEngine.h in Headers */, + 1F37176E1DDB9D1B009E537B /* RNCryptor tvOS.h in Headers */, ); - name = "Supporting Files"; - sourceTree = ""; + runOnlyForDeploymentPostprocessing = 0; + }; + 659134E61B14262B00B82A96 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 659134EE1B14262C00B82A96 /* RNCryptor iOS.h in Headers */, + 659135091B14271500B82A96 /* RNCryptor.h in Headers */, + 6591350A1B14271500B82A96 /* RNDecryptor.h in Headers */, + 6591350B1B14271500B82A96 /* RNEncryptor.h in Headers */, + 6591350C1B14271500B82A96 /* RNCryptorEngine.h in Headers */, + 6591350D1B14271500B82A96 /* RNCryptor+Private.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ AB13427715E0FC2300456914 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 90CAAF5A1737E408005C53B2 /* RNCryptor.h in Headers */, - 90CAAF5B1737E408005C53B2 /* RNDecryptor.h in Headers */, - 90CAAF5C1737E408005C53B2 /* RNEncryptor.h in Headers */, - 90CAAF5D1737E408005C53B2 /* RNOpenSSLCryptor.h in Headers */, - 90CAAF5E1737E408005C53B2 /* RNOpenSSLDecryptor.h in Headers */, - 90CAAF5F1737E408005C53B2 /* RNOpenSSLEncryptor.h in Headers */, - 90CAAF601737E408005C53B2 /* RNCryptorEngine.h in Headers */, - 90CAAF611737E408005C53B2 /* RNCryptor+Private.h in Headers */, + 4ABDC61718615875000DE03F /* RNCryptor.h in Headers */, + 4ABDC61D186158B2000DE03F /* RNDecryptor.h in Headers */, + 4ABDC61C18615894000DE03F /* RNCryptorEngine.h in Headers */, + 4ABDC61918615894000DE03F /* RNEncryptor.h in Headers */, + 4ABDC61E186158B2000DE03F /* RNCryptor+Private.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FB7564EE1512D3C4007B806B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FB75651F1512D7F8007B806B /* RNCryptor.h in Headers */, + FB7565241512D9BE007B8077 /* RNEncryptor.h in Headers */, + FB7565241512D9BE007B807B /* RNDecryptor.h in Headers */, + FB7565241512D9BE007B807F /* RNCryptorEngine.h in Headers */, + FB7565241512D9BE007B8085 /* RNCryptor+Private.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 1F3717521DDB9C5F009E537B /* RNCryptor watchOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F37175A1DDB9C60009E537B /* Build configuration list for PBXNativeTarget "RNCryptor watchOS" */; + buildPhases = ( + 1F37174E1DDB9C5F009E537B /* Sources */, + 1F37174F1DDB9C5F009E537B /* Frameworks */, + 1F3717501DDB9C5F009E537B /* Headers */, + 1F3717511DDB9C5F009E537B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "RNCryptor watchOS"; + productName = "RNCryptor watchOS"; + productReference = 1F3717531DDB9C5F009E537B /* RNCryptor.framework */; + productType = "com.apple.product-type.framework"; + }; + 1F3717691DDB9D1B009E537B /* RNCryptor tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F37176F1DDB9D1B009E537B /* Build configuration list for PBXNativeTarget "RNCryptor tvOS" */; + buildPhases = ( + 1F3717651DDB9D1B009E537B /* Sources */, + 1F3717661DDB9D1B009E537B /* Frameworks */, + 1F3717671DDB9D1B009E537B /* Headers */, + 1F3717681DDB9D1B009E537B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "RNCryptor tvOS"; + productName = "RNCryptor tvOS"; + productReference = 1F37176A1DDB9D1B009E537B /* RNCryptor.framework */; + productType = "com.apple.product-type.framework"; + }; + 659134E81B14262B00B82A96 /* RNCryptor iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 659135001B14262C00B82A96 /* Build configuration list for PBXNativeTarget "RNCryptor iOS" */; + buildPhases = ( + 659134E41B14262B00B82A96 /* Sources */, + 659134E51B14262B00B82A96 /* Frameworks */, + 659134E61B14262B00B82A96 /* Headers */, + 659134E71B14262B00B82A96 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "RNCryptor iOS"; + productName = "RNCryptor iOS"; + productReference = 659134E91B14262B00B82A96 /* RNCryptor.framework */; + productType = "com.apple.product-type.framework"; + }; AB13427915E0FC2300456914 /* RNCryptorOSX */ = { isa = PBXNativeTarget; buildConfigurationList = AB13428D15E0FC2300456914 /* Build configuration list for PBXNativeTarget "RNCryptorOSX" */; @@ -436,10 +617,10 @@ isa = PBXNativeTarget; buildConfigurationList = FB7565171512D3C5007B806B /* Build configuration list for PBXNativeTarget "RNCryptorTests" */; buildPhases = ( + FB53C198187F7A5400952674 /* ShellScript */, FB7564FB1512D3C4007B806B /* Sources */, FB7564FC1512D3C4007B806B /* Frameworks */, FB7564FD1512D3C4007B806B /* Resources */, - FB7564FE1512D3C4007B806B /* ShellScript */, ); buildRules = ( ); @@ -448,25 +629,8 @@ ); name = RNCryptorTests; productName = RNCryptTests; - productReference = FB7565001512D3C4007B806B /* RNCryptorTests.octest */; - productType = "com.apple.product-type.bundle.ocunit-test"; - }; - FBF7D58B167E5031004B6F0F /* RNCryptorVectors */ = { - isa = PBXNativeTarget; - buildConfigurationList = FBF7D596167E5032004B6F0F /* Build configuration list for PBXNativeTarget "RNCryptorVectors" */; - buildPhases = ( - FBF7D588167E5031004B6F0F /* Sources */, - FBF7D589167E5031004B6F0F /* Frameworks */, - FBF7D58A167E5031004B6F0F /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RNCryptorVectors; - productName = RNCryptorVectors; - productReference = FBF7D58C167E5031004B6F0F /* RNCryptorVectors */; - productType = "com.apple.product-type.tool"; + productReference = FB7565001512D3C4007B806B /* RNCryptorTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -475,12 +639,24 @@ isa = PBXProject; attributes = { CLASSPREFIX = RN; - LastTestingUpgradeCheck = 0600; - LastUpgradeCheck = 0600; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Rob Napier"; + TargetAttributes = { + 1F3717521DDB9C5F009E537B = { + CreatedOnToolsVersion = 8.2; + ProvisioningStyle = Automatic; + }; + 1F3717691DDB9D1B009E537B = { + CreatedOnToolsVersion = 8.2; + ProvisioningStyle = Automatic; + }; + 659134E81B14262B00B82A96 = { + CreatedOnToolsVersion = 6.3.2; + }; + }; }; buildConfigurationList = FB7564EA1512D3C4007B806B /* Build configuration list for PBXProject "RNCryptor" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 6.3"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -494,13 +670,37 @@ FB7564EF1512D3C4007B806B /* RNCryptor */, AB13427915E0FC2300456914 /* RNCryptorOSX */, FB7564FF1512D3C4007B806B /* RNCryptorTests */, - FBF7D58B167E5031004B6F0F /* RNCryptorVectors */, FB6AC68B16F6704100CA0C0A /* rncrypt */, + 659134E81B14262B00B82A96 /* RNCryptor iOS */, + 1F3717521DDB9C5F009E537B /* RNCryptor watchOS */, + 1F3717691DDB9D1B009E537B /* RNCryptor tvOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 1F3717511DDB9C5F009E537B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F3717681DDB9D1B009E537B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 659134E71B14262B00B82A96 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 659135081B14268500B82A96 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AB13427815E0FC2300456914 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -514,39 +714,76 @@ buildActionMask = 2147483647; files = ( FB75650E1512D3C4007B806B /* InfoPlist.strings in Resources */, - FB6CB6D7158FD093001F6D61 /* test.enc in Resources */, + FB6CB6D7158FD093001F6D61 /* openssl.enc in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - FB7564FE1512D3C4007B806B /* ShellScript */ = { + FB53C198187F7A5400952674 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/Spec/vectors/v3/kdf", + "$(SRCROOT)/Spec/vectors/v3/kdf-short", + "$(SRCROOT)/Spec/vectors/v3/key", + "$(SRCROOT)/Spec/vectors/v3/password", + "$(SRCROOT)/Spec/vectors/v3/password-short", ); outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/RNCryptorGenerateVectorTests.m", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; + shellPath = "/bin/sh -e -x"; + shellScript = "export LANG=en_US.UTF-8\nexport LANGUAGE=en_US.UTF-8\nexport LC_ALL=en_US.UTF-8\n\n${SRCROOT}/${TARGETNAME}/GenVectorTests -o ${SRCROOT}/RNCryptorTests/Generated/RNCryptorGeneratedVectorTests.m ${SRCROOT}/Spec/vectors\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 1F37174E1DDB9C5F009E537B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F37175C1DDB9CB0009E537B /* RNCryptor.m in Sources */, + 1F37175D1DDB9CB0009E537B /* RNDecryptor.m in Sources */, + 1F37175E1DDB9CB0009E537B /* RNEncryptor.m in Sources */, + 1F37175F1DDB9CB0009E537B /* RNCryptorEngine.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F3717651DDB9D1B009E537B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F3717781DDB9D5D009E537B /* RNEncryptor.m in Sources */, + 1F37177A1DDB9D63009E537B /* RNCryptorEngine.m in Sources */, + 1F3717761DDB9D56009E537B /* RNDecryptor.m in Sources */, + 1F3717741DDB9D50009E537B /* RNCryptor.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 659134E41B14262B00B82A96 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 659135021B14265A00B82A96 /* RNCryptor.m in Sources */, + 659135031B14265A00B82A96 /* RNDecryptor.m in Sources */, + 659135041B14265A00B82A96 /* RNEncryptor.m in Sources */, + 659135051B14265A00B82A96 /* RNCryptorEngine.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AB13427515E0FC2300456914 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - AB13428F15E0FC4600456914 /* RNOpenSSLDecryptor.m in Sources */, - AB13429015E0FC4600456914 /* RNOpenSSLEncryptor.m in Sources */, AB13429115E0FC4600456914 /* RNCryptorEngine.m in Sources */, AB13429215E0FC4600456914 /* RNDecryptor.m in Sources */, AB13429315E0FC4600456914 /* RNEncryptor.m in Sources */, - AB13429415E0FC4600456914 /* RNOpenSSLCryptor.m in Sources */, AB13429515E0FC4600456914 /* RNCryptor.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -568,12 +805,9 @@ buildActionMask = 2147483647; files = ( FB75651D1512D3E9007B806B /* RNCryptor.m in Sources */, - FB7565241512D9BE007B806D /* RNOpenSSLCryptor.m in Sources */, FB7565241512D9BE007B8075 /* RNEncryptor.m in Sources */, FB7565241512D9BE007B8079 /* RNDecryptor.m in Sources */, FB7565241512D9BE007B807D /* RNCryptorEngine.m in Sources */, - FB7565241512D9BE007B808B /* RNOpenSSLEncryptor.m in Sources */, - FB7565241512D9BE007B8091 /* RNOpenSSLDecryptor.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -581,15 +815,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FB30216118802ED900BF8F3C /* RNCryptorGeneratedVectorTests.m in Sources */, FB7565111512D3C5007B806B /* RNCryptorTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - FBF7D588167E5031004B6F0F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FBF7D591167E5032004B6F0F /* main.m in Sources */, + FB53C196187F6AB300952674 /* XCTestCase+RNCryptorVectorTests.m in Sources */, + FB6C961B185A0F7600CC2098 /* RNCryptorTestHelpers.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -624,10 +853,263 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 1F3717581DDB9C60009E537B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = "RNCryptor watchOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = net.robnapier.RNCryptor; + PRODUCT_NAME = RNCryptor; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 3.1; + }; + name = Debug; + }; + 1F3717591DDB9C60009E537B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = "RNCryptor watchOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.robnapier.RNCryptor; + PRODUCT_NAME = RNCryptor; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 3.1; + }; + name = Release; + }; + 1F3717701DDB9D1B009E537B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = "RNCryptor tvOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = net.robnapier.RNCryptor; + PRODUCT_NAME = RNCryptor; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 10.1; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 1F3717711DDB9D1B009E537B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = "RNCryptor tvOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.robnapier.RNCryptor; + PRODUCT_NAME = RNCryptor; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 10.1; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 659134FC1B14262C00B82A96 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + INFOPLIST_FILE = "RNCryptor iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "${SRCROOT}/RNCryptor iOS/module.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "net.robnapier.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = RNCryptor; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 659134FD1B14262C00B82A96 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + INFOPLIST_FILE = "RNCryptor iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "${SRCROOT}/RNCryptor iOS/module.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "net.robnapier.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = RNCryptor; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; AB13428B15E0FC2300456914 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -644,6 +1126,7 @@ INSTALL_PATH = "@rpath/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "net.robnapier.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = RNCryptor; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -655,7 +1138,6 @@ AB13428C15E0FC2300456914 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -683,7 +1165,6 @@ FB6AC69516F6704200CA0C0A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -705,7 +1186,6 @@ FB6AC69616F6704200CA0C0A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -728,11 +1208,23 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -741,10 +1233,15 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_THUMB_SUPPORT = NO; GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -753,16 +1250,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -775,6 +1287,10 @@ DSTROOT = /tmp/RNCryptor.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RNCryptor/RNCryptor-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + RNCRYPTOR_ALLOW_V1_BAD_HMAC, + ); GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = "$(SRCROOT)/../"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -793,6 +1309,7 @@ DSTROOT = /tmp/RNCryptor.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RNCryptor/RNCryptor-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = RNCRYPTOR_ALLOW_V1_BAD_HMAC; GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = "$(SRCROOT)/../"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -808,78 +1325,59 @@ FB7565181512D3C5007B806B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(DEVELOPER_LIBRARY_DIR)/Frameworks", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RNCryptor/RNCryptor-Prefix.pch"; GCC_THUMB_SUPPORT = NO; INFOPLIST_FILE = "RNCryptorTests/RNCryptorTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "net.robnapier.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = RNCryptorTests; - WRAPPER_EXTENSION = octest; }; name = Debug; }; FB7565191512D3C5007B806B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(DEVELOPER_LIBRARY_DIR)/Frameworks", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RNCryptor/RNCryptor-Prefix.pch"; GCC_THUMB_SUPPORT = NO; INFOPLIST_FILE = "RNCryptorTests/RNCryptorTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "net.robnapier.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = RNCryptorTests; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; - FBF7D597167E5032004B6F0F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "RNCryptorVectors/RNCryptorVectors-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - }; - name = Debug; - }; - FBF7D598167E5032004B6F0F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "RNCryptorVectors/RNCryptorVectors-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ""; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 1F37175A1DDB9C60009E537B /* Build configuration list for PBXNativeTarget "RNCryptor watchOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F3717581DDB9C60009E537B /* Debug */, + 1F3717591DDB9C60009E537B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1F37176F1DDB9D1B009E537B /* Build configuration list for PBXNativeTarget "RNCryptor tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F3717701DDB9D1B009E537B /* Debug */, + 1F3717711DDB9D1B009E537B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 659135001B14262C00B82A96 /* Build configuration list for PBXNativeTarget "RNCryptor iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 659134FC1B14262C00B82A96 /* Debug */, + 659134FD1B14262C00B82A96 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; AB13428D15E0FC2300456914 /* Build configuration list for PBXNativeTarget "RNCryptorOSX" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -925,15 +1423,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - FBF7D596167E5032004B6F0F /* Build configuration list for PBXNativeTarget "RNCryptorVectors" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FBF7D597167E5032004B6F0F /* Debug */, - FBF7D598167E5032004B6F0F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = FB7564E71512D3C4007B806B /* Project object */; diff --git a/RNCryptor.xcodeproj/project.xcworkspace/xcshareddata/RNCryptor.xccheckout b/RNCryptor.xcodeproj/project.xcworkspace/xcshareddata/RNCryptor.xccheckout new file mode 100644 index 00000000..2c8fb4ac --- /dev/null +++ b/RNCryptor.xcodeproj/project.xcworkspace/xcshareddata/RNCryptor.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 3ABD3F64-A1E8-41CD-8789-63CBB720A99A + IDESourceControlProjectName + RNCryptor + IDESourceControlProjectOriginsDictionary + + DEDD58F0BAF28034A74179391A23AC2E0219CDC3 + github.com:RNCryptor/RNCryptor.git + + IDESourceControlProjectPath + RNCryptor.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + DEDD58F0BAF28034A74179391A23AC2E0219CDC3 + ../.. + + IDESourceControlProjectURL + github.com:RNCryptor/RNCryptor.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + DEDD58F0BAF28034A74179391A23AC2E0219CDC3 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + DEDD58F0BAF28034A74179391A23AC2E0219CDC3 + IDESourceControlWCCName + RNCryptor + + + + diff --git a/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor OS X.xcscheme b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor OS X.xcscheme new file mode 100644 index 00000000..114da9a4 --- /dev/null +++ b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor OS X.xcscheme @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor iOS.xcscheme b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor iOS.xcscheme new file mode 100644 index 00000000..aa349889 --- /dev/null +++ b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor iOS.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor.xcscheme b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor.xcscheme new file mode 100644 index 00000000..a767c1f2 --- /dev/null +++ b/RNCryptor.xcodeproj/xcshareddata/xcschemes/RNCryptor.xcscheme @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNCryptor.xcodeproj/xcshareddata/xcschemes/rncrypt.xcscheme b/RNCryptor.xcodeproj/xcshareddata/xcschemes/rncrypt.xcscheme new file mode 100644 index 00000000..6d4bf22a --- /dev/null +++ b/RNCryptor.xcodeproj/xcshareddata/xcschemes/rncrypt.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNCryptor/RNCryptor.h b/RNCryptor/RNCryptor.h index b15259f3..bdd40293 100755 --- a/RNCryptor/RNCryptor.h +++ b/RNCryptor/RNCryptor.h @@ -5,17 +5,17 @@ // // This code is licensed under the MIT License: // -// Permission is hereby granted, free of charge, to any person obtaining a +// Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER @@ -25,10 +25,10 @@ // #import -#import -#import #import +// NOTE: No CommonCrypto types may be used in this file. Swift can't handle them. + extern NSString *const kRNCryptorErrorDomain; extern const uint8_t kRNCryptorFileVersion; @@ -36,47 +36,25 @@ typedef struct _RNCryptorKeyDerivationSettings { size_t keySize; size_t saltSize; - CCPBKDFAlgorithm PBKDFAlgorithm; - CCPseudoRandomAlgorithm PRF; + /* CCPBKDFAlgorithm */ uint32_t PBKDFAlgorithm; + /* CCPseudoRandomAlgorithm */ uint32_t PRF; uint rounds; + BOOL hasV2Password; // See Issue #77. V2 incorrectly handled multi-byte characters. } RNCryptorKeyDerivationSettings; typedef struct _RNCryptorSettings { - CCAlgorithm algorithm; + /* CCAlgorithm */ uint32_t algorithm; size_t blockSize; size_t IVSize; - CCOptions options; - CCHmacAlgorithm HMACAlgorithm; + /* CCOptions */ uint32_t options; + /* CCHmacAlgorithm */ uint32_t HMACAlgorithm; size_t HMACLength; RNCryptorKeyDerivationSettings keySettings; RNCryptorKeyDerivationSettings HMACKeySettings; } RNCryptorSettings; -static const RNCryptorSettings kRNCryptorAES256Settings = { - .algorithm = kCCAlgorithmAES128, - .blockSize = kCCBlockSizeAES128, - .IVSize = kCCBlockSizeAES128, - .options = kCCOptionPKCS7Padding, - .HMACAlgorithm = kCCHmacAlgSHA256, - .HMACLength = CC_SHA256_DIGEST_LENGTH, - - .keySettings = { - .keySize = kCCKeySizeAES256, - .saltSize = 8, - .PBKDFAlgorithm = kCCPBKDF2, - .PRF = kCCPRFHmacAlgSHA1, - .rounds = 10000 - }, - - .HMACKeySettings = { - .keySize = kCCKeySizeAES256, - .saltSize = 8, - .PBKDFAlgorithm = kCCPBKDF2, - .PRF = kCCPRFHmacAlgSHA1, - .rounds = 10000 - } -}; +extern const RNCryptorSettings kRNCryptorAES256Settings; enum _RNCryptorOptions { @@ -114,20 +92,20 @@ typedef void (^RNCryptorHandler)(RNCryptor *cryptor, NSData *data); - (void)finish; /** Generate key given a password and salt using a PBKDF -* -* @param password Password to use for PBKDF -* @param salt Salt for password -* @param keySettings Settings for the derivation (RNCryptorKeyDerivationSettings) -* @returns Key -* @throws if settings are illegal -*/ + * + * @param password Password to use for PBKDF + * @param salt Salt for password + * @param keySettings Settings for the derivation (RNCryptorKeyDerivationSettings) + * @returns Key + * @throws if settings are illegal + */ + (NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt settings:(RNCryptorKeyDerivationSettings)keySettings; /** Generate random data -* -* @param length Length of data to generate -* @returns random data -*/ + * + * @param length Length of data to generate + * @returns random data + */ + (NSData *)randomDataOfLength:(size_t)length; @end diff --git a/RNCryptor/RNCryptor.m b/RNCryptor/RNCryptor.m index c32e84e9..70a7e721 100755 --- a/RNCryptor/RNCryptor.m +++ b/RNCryptor/RNCryptor.m @@ -24,20 +24,54 @@ // DEALINGS IN THE SOFTWARE. // // + #import "RNCryptor.h" #import "RNCryptor+Private.h" + +#import +#import #import +#import + +const RNCryptorSettings kRNCryptorAES256Settings = { + .algorithm = kCCAlgorithmAES128, + .blockSize = kCCBlockSizeAES128, + .IVSize = kCCBlockSizeAES128, + .options = kCCOptionPKCS7Padding, + .HMACAlgorithm = kCCHmacAlgSHA256, + .HMACLength = CC_SHA256_DIGEST_LENGTH, + + .keySettings = { + .keySize = kCCKeySizeAES256, + .saltSize = 8, + .PBKDFAlgorithm = kCCPBKDF2, + .PRF = kCCPRFHmacAlgSHA1, + .rounds = 10000 + }, + + .HMACKeySettings = { + .keySize = kCCKeySizeAES256, + .saltSize = 8, + .PBKDFAlgorithm = kCCPBKDF2, + .PRF = kCCPRFHmacAlgSHA1, + .rounds = 10000 + } +}; +// Provide internal symbols for 10.6. These were made available in 10.7. +#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED +#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1060 extern int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) __attribute__((weak_import)); extern int CCKeyDerivationPBKDF( CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen, const uint8_t *salt, size_t saltLen, CCPseudoRandomAlgorithm prf, uint rounds, uint8_t *derivedKey, size_t derivedKeyLen) __attribute__((weak_import)); - +#endif +#endif NSString *const kRNCryptorErrorDomain = @"net.robnapier.RNCryptManager"; -const uint8_t kRNCryptorFileVersion = 2; +const uint8_t kRNCryptorFileVersion = 3; // TODO: This is a slightly expensive solution, but it's convenient. May want to create a "walkable" data object @implementation NSMutableData (RNCryptor) @@ -138,7 +172,9 @@ + (NSData *)synchronousResultForCryptor:(RNCryptor *)cryptor data:(NSData *)inDa case kCCPRFHmacAlgSHA256: return kCCPRFHmacAlgSHA256hlen; case kCCPRFHmacAlgSHA384: return kCCPRFHmacAlgSHA384hlen; case kCCPRFHmacAlgSHA512: return kCCPRFHmacAlgSHA512hlen; - default: return kCCPRFHmacAlgSHA256hlen; + default: + NSCAssert(NO, @"Unknown prf: %d", prf); + return 1; } } @@ -164,7 +200,7 @@ + (NSData *)synchronousResultForCryptor:(RNCryptor *)cryptor data:(NSData *)inDa } } -int +static int RN_CCKeyDerivationPBKDF( CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen, const uint8_t *salt, size_t saltLen, CCPseudoRandomAlgorithm prf, uint rounds, @@ -265,32 +301,38 @@ + (NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt settings:(RN { NSMutableData *derivedKey = [NSMutableData dataWithLength:keySettings.keySize]; - int result; - if (CCKeyDerivationPBKDF != NULL) { - result = CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm, // algorithm - password.UTF8String, // password - password.length, // passwordLength - salt.bytes, // salt - salt.length, // saltLen - keySettings.PRF, // PRF - keySettings.rounds, // rounds - derivedKey.mutableBytes, // derivedKey - derivedKey.length); // derivedKeyLen + // See Issue #77. V2 incorrectly calculated key for multi-byte characters. + NSData *passwordData; + if (keySettings.hasV2Password) { + passwordData = [NSData dataWithBytes:[password UTF8String] length:[password length]]; } else { - result = RN_CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm, // algorithm - password.UTF8String, // password - password.length, // passwordLength - salt.bytes, // salt - salt.length, // saltLen - keySettings.PRF, // PRF - keySettings.rounds, // rounds - derivedKey.mutableBytes, // derivedKey - derivedKey.length); // derivedKeyLen + passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; } + // Use the built-in PBKDF2 if it's available. Otherwise, we have our own. Hello crazy function pointer. + int result; + int (*PBKDF)(CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen, + const uint8_t *salt, size_t saltLen, + CCPseudoRandomAlgorithm prf, uint rounds, + uint8_t *derivedKey, size_t derivedKeyLen); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" + PBKDF = CCKeyDerivationPBKDF ?: RN_CCKeyDerivationPBKDF; +#pragma clang diagnostic pop + + result = PBKDF(keySettings.PBKDFAlgorithm, // algorithm + passwordData.bytes, // password + passwordData.length, // passwordLength + salt.bytes, // salt + salt.length, // saltLen + keySettings.PRF, // PRF + keySettings.rounds, // rounds + derivedKey.mutableBytes, // derivedKey + derivedKey.length); // derivedKeyLen + // Do not log password here - // TODO: Is is safe to assert here? We read salt from a file (but salt.length is internal). NSAssert(result == kCCSuccess, @"Unable to create AES key for password: %d", result); return derivedKey; @@ -321,7 +363,7 @@ + (NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt settings:(RN * * @APPLE_LICENSE_HEADER_END@ */ -int RN_SecRandomCopyBytes(void *rnd, size_t count, uint8_t *bytes) { +static int RN_SecRandomCopyBytes(void *rnd, size_t count, uint8_t *bytes) { static int kSecRandomFD; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -353,11 +395,14 @@ + (NSData *)randomDataOfLength:(size_t)length NSMutableData *data = [NSMutableData dataWithLength:length]; int result; - if (SecRandomCopyBytes != NULL) { + if (&SecRandomCopyBytes != NULL) { result = SecRandomCopyBytes(NULL, length, data.mutableBytes); } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" result = RN_SecRandomCopyBytes(NULL, length, data.mutableBytes); +#pragma clang diagnostic pop } NSAssert(result == 0, @"Unable to generate random bytes: %d", errno); @@ -369,12 +414,8 @@ - (id)initWithHandler:(RNCryptorHandler)handler NSParameterAssert(handler); self = [super init]; if (self) { - NSString *responseQueueName = [@"net.robnapier.response." stringByAppendingString:NSStringFromClass([self class])]; - _responseQueue = dispatch_queue_create([responseQueueName UTF8String], NULL); - -#if !OS_OBJECT_USE_OBJC - dispatch_retain(_responseQueue); -#endif + NSString *responseQueueName = [@"net.robnapier.response." stringByAppendingString:NSStringFromClass([self class])]; + _responseQueue = dispatch_queue_create([responseQueueName UTF8String], NULL); NSString *queueName = [@"net.robnapier." stringByAppendingString:NSStringFromClass([self class])]; _queue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL); @@ -447,4 +488,4 @@ - (BOOL)hasHMAC } -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNCryptorEngine.h b/RNCryptor/RNCryptorEngine.h index beb9e7d9..71060c17 100644 --- a/RNCryptor/RNCryptorEngine.h +++ b/RNCryptor/RNCryptorEngine.h @@ -32,4 +32,4 @@ - (RNCryptorEngine *)initWithOperation:(CCOperation)operation settings:(RNCryptorSettings)settings key:(NSData *)key IV:(NSData *)IV error:(NSError **)error; - (NSData *)addData:(NSData *)data error:(NSError **)error; - (NSData *)finishWithError:(NSError **)error; -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNCryptorEngine.m b/RNCryptor/RNCryptorEngine.m index 32a1c486..4e1e1c30 100644 --- a/RNCryptor/RNCryptorEngine.m +++ b/RNCryptor/RNCryptorEngine.m @@ -112,4 +112,4 @@ - (NSData *)finishWithError:(NSError **)error return [buffer subdataWithRange:NSMakeRange(0, dataOutMoved)]; } -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNDecryptor.h b/RNCryptor/RNDecryptor.h index 6149036c..25d1b9ed 100644 --- a/RNCryptor/RNDecryptor.h +++ b/RNCryptor/RNDecryptor.h @@ -43,4 +43,4 @@ + (NSData *)decryptData:(NSData *)data withPassword:(NSString *)password error:(NSError **)error; + (NSData *)decryptData:(NSData *)data withEncryptionKey:(NSData *)encryptionKey HMACKey:(NSData *)HMACKey error:(NSError **)error; -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNDecryptor.m b/RNCryptor/RNDecryptor.m index c7c0a5fa..b2c3628b 100644 --- a/RNCryptor/RNDecryptor.m +++ b/RNCryptor/RNDecryptor.m @@ -24,13 +24,59 @@ // DEALINGS IN THE SOFTWARE. // - -#import "RNCryptor+Private.h" #import "RNDecryptor.h" +#import "RNCryptor+Private.h" #import "RNCryptorEngine.h" +#import + static const NSUInteger kPreambleSize = 2; +@interface NSData (RNCryptor_ConsistentCompare) + +/** Compare two NSData in time proportional to the compared data (otherData) + * + * isEqual:-based comparisons stop comparing at the first difference. This can be used by attackers, in some situations, + * to determine a secret value by considering the time required to compare the values. + * + * It is slightly better to call this as [secret rnc_isEqualInConsistentTime:attackersData] rather than the reverse, + * but it is not a major issue either way. In the first case, the time required is proportional to the attacker's data, + * which provides the attacker no information about the length of secret. In the second case, the time is proportional + * to the length of secret, which leaks a small amount of informaiont, but in a way that does not varry in proportion to + * the attacker's data. + * + * @param otherData data to compare + * @returns YES if values are equal + */ +- (BOOL)rnc_isEqualInConsistentTime:(NSData *)otherData; + +@end + +@implementation NSData (RNCryptor_ConstantCompare) + +- (BOOL)rnc_isEqualInConsistentTime:(NSData *)otherData { + // The point of this routine is XOR the bytes of each data and accumulate the results with OR. + // If any bytes are different, then the OR will accumulate some non-0 value. + + const uint8_t *myBytes = [self bytes]; + const NSUInteger myLength = [self length]; + const uint8_t *otherBytes = [otherData bytes]; + const NSUInteger otherLength = [otherData length]; + + uint8_t result = otherLength != myLength; // Start with 0 (equal) only if our lengths are equal + + for (NSUInteger i = 0; i < otherLength; ++i) { + // Use mod to wrap around ourselves if they are longer than we are. + // Remember, we already broke equality if our lengths are different. + result |= myBytes[i % myLength] ^ otherBytes[i]; + } + + return result == 0; +} + +@end + + @interface RNDecryptor () @property (nonatomic, readonly, strong) NSMutableData *inData; @property (nonatomic, readwrite, copy) NSData *encryptionKey; @@ -102,7 +148,7 @@ - (RNDecryptor *)initWithPassword:(NSString *)aPassword handler:(RNCryptorHandle self = [self initWithEncryptionKey:nil HMACKey:nil handler:aHandler]; if (self) { - _password = aPassword; + _password = [aPassword copy]; _settings = kRNCryptorAES256Settings; } return self; @@ -172,6 +218,16 @@ - (BOOL)updateOptionsForPreamble:(NSData *)preamble } #endif + if (bytes[0] == 2) { + self.options = bytes[1]; + + RNCryptorSettings settings = self.settings; + settings.keySettings.hasV2Password = YES; + settings.HMACKeySettings.hasV2Password = YES; + self.settings = settings; + return YES; + } + if (bytes[0] == kRNCryptorFileVersion) { self.options = bytes[1]; return YES; @@ -208,15 +264,18 @@ - (void)consumeHeaderFromData:(NSMutableData *)data [[data _RNConsumeToIndex:kPreambleSize] mutableCopy]; // Throw away the preamble NSError *error = nil; - if (self.options & kRNCryptorOptionHasPassword) { - NSAssert(!self.encryptionKey && !self.HMACKey, @"Both password and the key (%d) or HMACKey (%d) are set.", self.encryptionKey != nil, self.HMACKey != nil); - - NSData *encryptionKeySalt = [data _RNConsumeToIndex:self.settings.keySettings.saltSize]; - NSData *HMACKeySalt = [data _RNConsumeToIndex:self.settings.HMACKeySettings.saltSize]; - self.encryptionKey = [[self class] keyForPassword:self.password salt:encryptionKeySalt settings:self.settings.keySettings]; - self.HMACKey = [[self class] keyForPassword:self.password salt:HMACKeySalt settings:self.settings.HMACKeySettings]; - self.password = nil; // Don't need this anymore. + // If we were called with a password and the format thinks there's a password + // (The format might think there's a password because it's corrupt, and we don't want to assert in that case.) + if ((self.options & kRNCryptorOptionHasPassword) && self.password) { + NSAssert(!self.encryptionKey && !self.HMACKey, @"Both password and the key (%d) or HMACKey (%d) are set.", self.encryptionKey != nil, self.HMACKey != nil); + + NSData *encryptionKeySalt = [data _RNConsumeToIndex:self.settings.keySettings.saltSize]; + NSData *HMACKeySalt = [data _RNConsumeToIndex:self.settings.HMACKeySettings.saltSize]; + self.encryptionKey = [[self class] keyForPassword:self.password salt:encryptionKeySalt settings:self.settings.keySettings]; + self.HMACKey = [[self class] keyForPassword:self.password salt:HMACKeySalt settings:self.settings.HMACKeySettings]; + + self.password = nil; // Don't need this anymore. } NSData *IV = [data _RNConsumeToIndex:self.settings.IVSize]; @@ -247,6 +306,20 @@ - (void)finish dispatch_async(self.queue, ^{ NSError *error = nil; + + if (self.hasHMAC) { + NSMutableData *HMACData = [NSMutableData dataWithLength:self.HMACLength]; + CCHmacFinal(&_HMACContext, [HMACData mutableBytes]); + + if (![HMACData rnc_isEqualInConsistentTime:self.inData]) { + [self cleanupAndNotifyWithError:[NSError errorWithDomain:kRNCryptorErrorDomain + code:kRNCryptorHMACMismatch + userInfo:[NSDictionary dictionaryWithObject:@"HMAC Mismatch" /* DNL */ + forKey:NSLocalizedDescriptionKey]]]; + return; + } + } + NSData *decryptedData = [self.engine finishWithError:&error]; if (!decryptedData) { @@ -255,21 +328,8 @@ - (void)finish } [self.outData appendData:decryptedData]; - if (self.hasHMAC) { - NSMutableData *HMACData = [NSMutableData dataWithLength:self.HMACLength]; - CCHmacFinal(&_HMACContext, [HMACData mutableBytes]); - - if (![HMACData isEqualToData:self.inData]) { - [self cleanupAndNotifyWithError:[NSError errorWithDomain:kRNCryptorErrorDomain - code:kRNCryptorHMACMismatch - userInfo:[NSDictionary dictionaryWithObject:@"HMAC Mismatch" /* DNL */ - forKey:NSLocalizedDescriptionKey]]]; - return; - } - } - [self cleanupAndNotifyWithError:nil]; }); } -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNEncryptor.h b/RNCryptor/RNEncryptor.h index dcf0a0f5..94c9e971 100644 --- a/RNCryptor/RNEncryptor.h +++ b/RNCryptor/RNEncryptor.h @@ -33,11 +33,45 @@ HMACKey:(NSData *)HMACKey handler:(RNCryptorHandler)handler; + - (RNEncryptor *)initWithSettings:(RNCryptorSettings)settings password:(NSString *)password handler:(RNCryptorHandler)handler; +// This form with manual IV is generally only used for testing +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings + encryptionKey:(NSData *)anEncryptionKey + HMACKey:(NSData *)anHMACKey + IV:(NSData *)anIV + handler:(RNCryptorHandler)aHandler; + +// This form with manual IV and salts is generally only used for testing +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)settings + password:(NSString *)password + IV:(NSData *)anIV + encryptionSalt:(NSData *)anEncryptionSalt + HMACSalt:(NSData *)anHMACSalt + handler:(RNCryptorHandler)handler; + + + (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings password:(NSString *)password error:(NSError **)error; + (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey HMACKey:(NSData *)HMACKey error:(NSError **)error; -@end \ No newline at end of file +// This form with manual IV is generally only used for testing ++ (NSData *)encryptData:(NSData *)thePlaintext + withSettings:(RNCryptorSettings)theSettings + encryptionKey:(NSData *)anEncryptionKey + HMACKey:(NSData *)anHMACKey + IV:(NSData *)anIV + error:(NSError **)anError; + +// This form with manual IV and salts is generally only used for testing ++ (NSData *)encryptData:(NSData *)data + withSettings:(RNCryptorSettings)settings + password:(NSString *)password + IV:(NSData *)anIV + encryptionSalt:(NSData *)anEncryptionSalt + HMACSalt:(NSData *)anHMACSalt + error:(NSError **)error; + +@end diff --git a/RNCryptor/RNEncryptor.m b/RNCryptor/RNEncryptor.m index 0ba2eccb..7be85bdd 100644 --- a/RNCryptor/RNEncryptor.m +++ b/RNCryptor/RNEncryptor.m @@ -24,11 +24,12 @@ // DEALINGS IN THE SOFTWARE. // - -#import "RNCryptor+Private.h" #import "RNEncryptor.h" +#import "RNCryptor+Private.h" #import "RNCryptorEngine.h" +#import + @interface RNEncryptor () @property (nonatomic, readwrite, strong) NSData *encryptionSalt; @property (nonatomic, readwrite, strong) NSData *HMACSalt; @@ -54,8 +55,24 @@ + (NSData *)encryptData:(NSData *)thePlaintext withSettings:(RNCryptorSettings)t return [self synchronousResultForCryptor:cryptor data:thePlaintext error:anError]; } -+ (NSData *)encryptData:(NSData *)thePlaintext withSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey HMACKey:(NSData *)anHMACKey error:(NSError **)anError ++ (NSData *)encryptData:(NSData *)thePlaintext + withSettings:(RNCryptorSettings)theSettings + password:(NSString *)aPassword + IV:(NSData *)anIV + encryptionSalt:(NSData *)anEncryptionSalt + HMACSalt:(NSData *)anHMACSalt + error:(NSError **)anError { + RNEncryptor *cryptor = [[self alloc] initWithSettings:theSettings + password:aPassword + IV:anIV + encryptionSalt:anEncryptionSalt + HMACSalt:anHMACSalt + handler:^(RNCryptor *c, NSData *d) {}]; + return [self synchronousResultForCryptor:cryptor data:thePlaintext error:anError]; +} + ++ (NSData *)encryptData:(NSData *)thePlaintext withSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey HMACKey:(NSData *)anHMACKey error:(NSError **)anError { RNEncryptor *cryptor = [[self alloc] initWithSettings:theSettings encryptionKey:anEncryptionKey HMACKey:anHMACKey @@ -63,11 +80,42 @@ + (NSData *)encryptData:(NSData *)thePlaintext withSettings:(RNCryptorSettings)t return [self synchronousResultForCryptor:cryptor data:thePlaintext error:anError]; } -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey HMACKey:(NSData *)anHMACKey handler:(RNCryptorHandler)aHandler + ++ (NSData *)encryptData:(NSData *)thePlaintext + withSettings:(RNCryptorSettings)theSettings + encryptionKey:(NSData *)anEncryptionKey + HMACKey:(NSData *)anHMACKey + IV:(NSData *)anIV + error:(NSError **)anError +{ + RNEncryptor *cryptor = [[self alloc] initWithSettings:theSettings + encryptionKey:anEncryptionKey + HMACKey:anHMACKey + IV:anIV + handler:^(RNCryptor *c, NSData *d) {}]; + return [self synchronousResultForCryptor:cryptor data:thePlaintext error:anError]; +} + +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings + encryptionKey:(NSData *)anEncryptionKey + HMACKey:(NSData *)anHMACKey + handler:(RNCryptorHandler)aHandler { + return [self initWithSettings:kRNCryptorAES256Settings + encryptionKey:anEncryptionKey + HMACKey:anHMACKey + IV:[[self class] randomDataOfLength:theSettings.IVSize] + handler:aHandler]; +} + +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings + encryptionKey:(NSData *)anEncryptionKey + HMACKey:(NSData *)anHMACKey + IV:(NSData *)anIV + handler:(RNCryptorHandler)aHandler { self = [super initWithHandler:aHandler]; if (self) { - self.IV = [[self class] randomDataOfLength:theSettings.IVSize]; + self.IV = anIV; if (anHMACKey) { CCHmacInit(&_HMACContext, theSettings.HMACAlgorithm, anHMACKey.bytes, anHMACKey.length); @@ -90,24 +138,40 @@ - (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:( return self; } -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings password:(NSString *)aPassword handler:(RNCryptorHandler)aHandler -{ - NSParameterAssert(aPassword != nil); +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings password:(NSString *)aPassword handler:(RNCryptorHandler)aHandler { + return [self initWithSettings:theSettings + password:aPassword + IV:[[self class] randomDataOfLength:theSettings.IVSize] + encryptionSalt:[[self class] randomDataOfLength:theSettings.keySettings.saltSize] + HMACSalt:[[self class] randomDataOfLength:theSettings.HMACKeySettings.saltSize] + handler:aHandler]; +} - NSData *encryptionSalt = [[self class] randomDataOfLength:theSettings.keySettings.saltSize]; - NSData *encryptionKey = [[self class] keyForPassword:aPassword salt:encryptionSalt settings:theSettings.keySettings]; - NSData *HMACSalt = [[self class] randomDataOfLength:theSettings.HMACKeySettings.saltSize]; - NSData *HMACKey = [[self class] keyForPassword:aPassword salt:HMACSalt settings:theSettings.HMACKeySettings]; +- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings + password:(NSString *)aPassword + IV:(NSData *)anIV + encryptionSalt:(NSData *)anEncryptionSalt + HMACSalt:(NSData *)anHMACSalt + handler:(RNCryptorHandler)aHandler; +{ + NSParameterAssert(aPassword.length > 0); // We'll go forward, but this is undefined behavior for RNCryptor + NSParameterAssert(anIV); + NSParameterAssert(anEncryptionSalt); + NSParameterAssert(anHMACSalt); + + NSData *encryptionKey = [[self class] keyForPassword:aPassword salt:anEncryptionSalt settings:theSettings.keySettings]; + NSData *HMACKey = [[self class] keyForPassword:aPassword salt:anHMACSalt settings:theSettings.HMACKeySettings]; self = [self initWithSettings:theSettings encryptionKey:encryptionKey HMACKey:HMACKey + IV:anIV handler:aHandler]; if (self) { self.options |= kRNCryptorOptionHasPassword; - self.encryptionSalt = encryptionSalt; - self.HMACSalt = HMACSalt; + self.encryptionSalt = anEncryptionSalt; + self.HMACSalt = anHMACSalt; } return self; } @@ -178,4 +242,4 @@ - (void)finish }); } -@end \ No newline at end of file +@end diff --git a/RNCryptor/RNOpenSSLCryptor.h b/RNCryptor/RNOpenSSLCryptor.h deleted file mode 100644 index a8284081..00000000 --- a/RNCryptor/RNOpenSSLCryptor.h +++ /dev/null @@ -1,69 +0,0 @@ -// -// RNOpenSSLCryptor -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#import "RNOpenSSLDecryptor.h" -#import "RNOpenSSLEncryptor.h" - - -extern NSString *const kRNCryptorOpenSSLSaltedString; - -NSData *RNOpenSSLCryptorGetKey(NSString *password, NSData *salt, RNCryptorKeyDerivationSettings keySettings); -NSData *RNOpenSSLCryptorGetIV(NSData *key, NSString *password, NSData *salt, RNCryptorKeyDerivationSettings keySettings); - - -// -//#import "RNCryptor.h" -// -// -//@interface RNOpenSSLCryptor : NSObject -//+ (RNOpenSSLCryptor *)openSSLCryptor; -// -//- (BOOL)encryptFromStream:(NSInputStream *)fromStream -// toStream:(NSOutputStream *)toStream -// password:(NSString *)password -// error:(NSError **)error; -// -//- (BOOL)decryptFromStream:(NSInputStream *)fromStream -// toStream:(NSOutputStream *)toStream -// password:(NSString *)password -// error:(NSError **)error; -// -//@end -// -//static const RNCryptorSettings kRNCryptorOpenSSLSettings = { -// .algorithm = kCCAlgorithmAES128, -// .mode = kCCModeCBC, -// .blockSize = kCCBlockSizeAES128, -// .IVSize = kCCBlockSizeAES128, -// .padding = ccPKCS7Padding, -// -// .keySettings = { -// .keySize = kCCKeySizeAES256, -// .saltSize = 8, -// .rounds = 1, -// .PRF = kCCPRFHmacAlgSHA1 -// }, -//}; diff --git a/RNCryptor/RNOpenSSLCryptor.m b/RNCryptor/RNOpenSSLCryptor.m deleted file mode 100644 index 6eabec42..00000000 --- a/RNCryptor/RNOpenSSLCryptor.m +++ /dev/null @@ -1,316 +0,0 @@ -//// -//// RNOpenSSLCryptor -//// -//// Copyright (c) 2012 Rob Napier -//// -//// This code is licensed under the MIT License: -//// -//// Permission is hereby granted, free of charge, to any person obtaining a -//// copy of this software and associated documentation files (the "Software"), -//// to deal in the Software without restriction, including without limitation -//// the rights to use, copy, modify, merge, publish, distribute, sublicense, -//// and/or sell copies of the Software, and to permit persons to whom the -//// Software is furnished to do so, subject to the following conditions: -//// -//// The above copyright notice and this permission notice shall be included in -//// all copies or substantial portions of the Software. -//// -//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -//// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -//// DEALINGS IN THE SOFTWARE. -//// - - -// For aes-128: -// -// key = MD5(password + salt) -// IV = MD5(Key + password + salt) - -// -// For aes-256: -// -// Hash0 = '' -// Hash1 = MD5(Hash0 + Password + Salt) -// Hash2 = MD5(Hash1 + Password + Salt) -// Hash3 = MD5(Hash2 + Password + Salt) -// Hash4 = MD5(Hash3 + Password + Salt) -// -// Key = Hash1 + Hash2 -// IV = Hash3 + Hash4 -// - -// File Format: -// -// |Salted___||| -// - -#import "RNOpenSSLCryptor.h" - -NSString *const kRNCryptorOpenSSLSaltedString = @"Salted__"; - -static NSData *GetHashForHash(NSData *hash, NSData *passwordSalt) { - unsigned char md[CC_MD5_DIGEST_LENGTH]; - - NSMutableData *hashMaterial = [NSMutableData dataWithData:hash]; - [hashMaterial appendData:passwordSalt]; - CC_MD5([hashMaterial bytes], (CC_LONG)[hashMaterial length], md); - - return [NSData dataWithBytes:md length:sizeof(md)]; -} - - -NSData *RNOpenSSLCryptorGetKey(NSString *password, NSData *salt, RNCryptorKeyDerivationSettings keySettings) { - // FIXME: This is all very inefficient; we repeat ourselves in IVForKey:... - - NSData *key; - NSMutableData *passwordSalt = [[password dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; - [passwordSalt appendData:salt]; - - if (keySettings.keySize != kCCKeySizeAES256) { - // For aes-128: - // - // key = MD5(password + salt) - // IV = MD5(Key + password + salt) - unsigned char md[CC_MD5_DIGEST_LENGTH]; - CC_MD5([passwordSalt bytes], (CC_LONG)[passwordSalt length], md); - key = [NSData dataWithBytes:md length:sizeof(md)]; - - } else { - // Hash0 = '' - // Hash1 = MD5(Hash0 + Password + Salt) - // Hash2 = MD5(Hash1 + Password + Salt) - // Hash3 = MD5(Hash2 + Password + Salt) - // Hash4 = MD5(Hash3 + Password + Salt) - // - // Key = Hash1 + Hash2 - // IV = Hash3 + Hash4 - - NSData *hash1 = GetHashForHash(nil, passwordSalt); - NSData *hash2 = GetHashForHash(hash1, passwordSalt); - - key = [hash1 mutableCopy]; - [(NSMutableData*)key appendData:hash2]; - } - return key; -} - -NSData *RNOpenSSLCryptorGetIV(NSData *key, NSString *password, NSData *salt, RNCryptorKeyDerivationSettings keySettings) { - - NSMutableData *IV; - NSMutableData *passwordSalt = [[password dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; - [passwordSalt appendData:salt]; - - if (keySettings.keySize != kCCKeySizeAES256) { - // For aes-128: - // - // key = MD5(password + salt) - // IV = MD5(Key + password + salt) - IV = [GetHashForHash(key, passwordSalt) mutableCopy]; - - } else { - - // - // For aes-256: - // - // Hash0 = '' - // Hash1 = MD5(Hash0 + Password + Salt) - // Hash2 = MD5(Hash1 + Password + Salt) - // Hash3 = MD5(Hash2 + Password + Salt) - // Hash4 = MD5(Hash3 + Password + Salt) - // - // Key = Hash1 + Hash2 - // IV = Hash3 + Hash4 - NSData *hash1 = GetHashForHash(nil, passwordSalt); - NSData *hash2 = GetHashForHash(hash1, passwordSalt); - NSData *hash3 = GetHashForHash(hash2, passwordSalt); - NSData *hash4 = GetHashForHash(hash3, passwordSalt); - - IV = [hash3 mutableCopy]; - [IV appendData:hash4]; - } - return IV; -} - - - -// -//const NSUInteger kSaltSize = 8; -//NSString *const kSaltedString = @"Salted__"; -// -//@interface NSInputStream (RNCryptor) -//- (BOOL)_RNGetData:(NSData **)data maxLength:(NSUInteger)maxLength error:(NSError **)error; -//@end -// -//@implementation NSInputStream (RNCryptor) -//- (BOOL)_RNGetData:(NSData **)data maxLength:(NSUInteger)maxLength error:(NSError **)error -//{ -// NSMutableData *buffer = [NSMutableData dataWithLength:maxLength]; -// if ([self read:buffer.mutableBytes maxLength:maxLength] < 0) { -// if (error) { -// *error = [self streamError]; -// return NO; -// } -// } -// -// *data = buffer; -// return YES; -//} -//@end -// -//@interface NSOutputStream (RNCryptor) -//- (BOOL)_RNWriteData:(NSData *)data error:(NSError **)error; -//@end -// -//@implementation NSOutputStream (RNCryptor) -//- (BOOL)_RNWriteData:(NSData *)data error:(NSError **)error -//{ -// // Writing 0 bytes will close the output stream. -// // This is an undocumented side-effect. radar://9930518 -// if (data.length > 0) { -// NSInteger bytesWritten = [self write:data.bytes -// maxLength:data.length]; -// if (bytesWritten != data.length) { -// if (error) { -// *error = [self streamError]; -// } -// return NO; -// } -// } -// return YES; -//} -//@end -// -//@interface RNOpenSSLCryptor () -//@end -// -//@implementation RNOpenSSLCryptor -//+ (RNOpenSSLCryptor *)openSSLCryptor -//{ -// static dispatch_once_t once; -// static id openSSLCryptor = nil; -// -// dispatch_once(&once, ^{openSSLCryptor = [[self alloc] init];}); -// return openSSLCryptor; -//} -// -//- (NSData *)hashForHash:(NSData *)hash passwordSalt:(NSData *)passwordSalt -//{ -// unsigned char md[CC_MD5_DIGEST_LENGTH]; -// -// NSMutableData *hashMaterial = [NSMutableData dataWithData:hash]; -// [hashMaterial appendData:passwordSalt]; -// CC_MD5([hashMaterial bytes], [hashMaterial length], md); -// -// return [NSData dataWithBytes:md length:sizeof(md)]; -//} -// -//- (NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt -//{ -// // FIXME: This is all very inefficient; we repeat ourselves in IVForKey:... -// -// // Hash0 = '' -// // Hash1 = MD5(Hash0 + Password + Salt) -// // Hash2 = MD5(Hash1 + Password + Salt) -// // Hash3 = MD5(Hash2 + Password + Salt) -// // Hash4 = MD5(Hash3 + Password + Salt) -// // -// // Key = Hash1 + Hash2 -// // IV = Hash3 + Hash4 -// -// NSMutableData *passwordSalt = [[password dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; -// [passwordSalt appendData:salt]; -// -// NSData *hash1 = [self hashForHash:nil passwordSalt:passwordSalt]; -// NSData *hash2 = [self hashForHash:hash1 passwordSalt:passwordSalt]; -// -// NSMutableData *key = [hash1 mutableCopy]; -// [key appendData:hash2]; -// -// return key; -// -//// // key = MD5(password + salt) -//// unsigned char md[CC_MD5_DIGEST_LENGTH]; -//// NSMutableData *keyMaterial = [NSMutableData dataWithData:[password dataUsingEncoding:NSUTF8StringEncoding]]; -//// [keyMaterial appendData:salt]; -//// CC_MD5([keyMaterial bytes], [keyMaterial length], md); -//// NSData *key = [NSData dataWithBytes:md length:sizeof(md)]; -//// return key; -//} -// -//- (NSData *)IVForKey:(NSData *)key password:(NSString *)password salt:(NSData *)salt -//{ -// NSMutableData *passwordSalt = [[password dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; -// [passwordSalt appendData:salt]; -// -// NSData *hash1 = [self hashForHash:nil passwordSalt:passwordSalt]; -// NSData *hash2 = [self hashForHash:hash1 passwordSalt:passwordSalt]; -// NSData *hash3 = [self hashForHash:hash2 passwordSalt:passwordSalt]; -// NSData *hash4 = [self hashForHash:hash3 passwordSalt:passwordSalt]; -// -// NSMutableData *IV = [hash3 mutableCopy]; -// [IV appendData:hash4]; -// -// return IV; -// -// -//// // IV = MD5(Key + password + salt) -//// unsigned char md[CC_MD5_DIGEST_LENGTH]; -//// NSMutableData *IVMaterial = [NSMutableData dataWithData:key]; -//// [IVMaterial appendData:[password dataUsingEncoding:NSUTF8StringEncoding]]; -//// [IVMaterial appendData:salt]; -//// CC_MD5([IVMaterial bytes], [IVMaterial length], md); -//// NSData *IV = [NSData dataWithBytes:md length:sizeof(md)]; -//// return IV; -//} -// -//- (BOOL)decryptFromStream:(NSInputStream *)fromStream toStream:(NSOutputStream *)toStream password:(NSString *)password error:(NSError **)error -//{ -// NSData *salted; -// NSData *encryptionKeySalt; -// -// [fromStream open]; -// -// if (![fromStream _RNGetData:&salted maxLength:[kSaltedString length] error:error] || -// ![fromStream _RNGetData:&encryptionKeySalt maxLength:kSaltSize error:error]) { -// return NO; -// } -// -// if (![[[NSString alloc] initWithData:salted encoding:NSUTF8StringEncoding] isEqualToString:kSaltedString]) { -// if (error) { -// *error = [NSError errorWithDomain:kRNCryptorErrorDomain code:kRNCryptorUnknownHeader -// userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"Could not find salt", @"Could not find salt") forKey:NSLocalizedDescriptionKey]]; -// } -// return NO; -// } -// -// NSData *encryptionKey = [self keyForPassword:password salt:encryptionKeySalt]; -// NSData *IV = [self IVForKey:encryptionKey password:password salt:encryptionKeySalt]; -// -// RNCryptor *cryptor = [[RNCryptor alloc] initWithSettings:kRNCryptorOpenSSLSettings]; -// -// return [cryptor performOperation:kCCDecrypt fromStream:fromStream readCallback:nil toStream:toStream writeCallback:nil encryptionKey:encryptionKey IV:IV footerSize:0 footer:nil error:error]; -//} -// -// -//- (BOOL)encryptFromStream:(NSInputStream *)fromStream toStream:(NSOutputStream *)toStream password:(NSString *)password error:(NSError **)error -//{ -// NSData *encryptionKeySalt = [RNCryptor randomDataOfLength:kSaltSize]; -// NSData *encryptionKey = [self keyForPassword:password salt:encryptionKeySalt]; -// NSData *IV = [self IVForKey:encryptionKey password:password salt:encryptionKeySalt]; -// -// [toStream open]; -// NSData *headerData = [kSaltedString dataUsingEncoding:NSUTF8StringEncoding]; -// if (![toStream _RNWriteData:headerData error:error] || -// ![toStream _RNWriteData:encryptionKeySalt error:error] -// ) { -// return NO; -// } -// -// RNCryptor *cryptor = [[RNCryptor alloc] initWithSettings:kRNCryptorOpenSSLSettings]; -// return [cryptor performOperation:kCCEncrypt fromStream:fromStream readCallback:nil toStream:toStream writeCallback:nil encryptionKey:encryptionKey IV:IV footerSize:0 footer:nil error:error]; -//} -//@end diff --git a/RNCryptor/RNOpenSSLDecryptor.h b/RNCryptor/RNOpenSSLDecryptor.h deleted file mode 100644 index 09ec0658..00000000 --- a/RNCryptor/RNOpenSSLDecryptor.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// RNOpenSSLDecryptor -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#import -#import "RNDecryptor.h" - -@interface RNOpenSSLDecryptor : RNDecryptor -- (RNDecryptor *)initWithSettings:(RNCryptorSettings)settings - password:(NSString *)password - handler:(RNCryptorHandler)handler; - -- (RNDecryptor *)initWithSettings:(RNCryptorSettings)theSettings - encryptionKey:(NSData *)anEncryptionKey - IV:(NSData *)anIV - handler:(RNCryptorHandler)aHandler; - -+ (NSData *)decryptData:(NSData *)data withSettings:(RNCryptorSettings)settings password:(NSString *)password error:(NSError **)error; -+ (NSData *)decryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey IV:(NSData *)IV error:(NSError **)error; - -@end \ No newline at end of file diff --git a/RNCryptor/RNOpenSSLDecryptor.m b/RNCryptor/RNOpenSSLDecryptor.m deleted file mode 100644 index 0c6b68e9..00000000 --- a/RNCryptor/RNOpenSSLDecryptor.m +++ /dev/null @@ -1,158 +0,0 @@ -// -// RNOpenSSLDecryptor -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#import "RNOpenSSLDecryptor.h" -#import "RNCryptor+Private.h" -#import "RNCryptorEngine.h" -#import "RNOpenSSLCryptor.h" - -@interface RNDecryptor (Private) -@property (nonatomic, readwrite, strong) NSMutableData *inData; -@property (nonatomic, readwrite, copy) NSData *encryptionKey; -@property (nonatomic, readwrite, copy) NSData *HMACKey; -@property (nonatomic, readwrite, copy) NSString *password; -@end - -@interface RNOpenSSLDecryptor () -@property (nonatomic, readwrite, assign) RNCryptorSettings settings; -@property (nonatomic, readwrite, copy) NSString *password; -@end - -@implementation RNOpenSSLDecryptor -@synthesize password = _password; -@synthesize settings = _settings; - -+ (NSData *)decryptData:(NSData *)data withSettings:(RNCryptorSettings)settings password:(NSString *)password error:(NSError **)error -{ - RNDecryptor *cryptor = [[self alloc] initWithSettings:settings password:password handler:^(RNCryptor *c, NSData *d) {}]; - return [self synchronousResultForCryptor:cryptor data:data error:error]; -} - -+ (NSData *)decryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey IV:(NSData *)IV error:(NSError **)error -{ - RNDecryptor *cryptor = [[self alloc] initWithSettings:settings encryptionKey:encryptionKey IV:IV handler:^(RNCryptor *c, NSData *d) {}]; - return [self synchronousResultForCryptor:cryptor data:data error:error]; -} - -- (RNDecryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey IV:(NSData *)anIV handler:(RNCryptorHandler)aHandler -{ - NSParameterAssert(anEncryptionKey != nil); - - self = [super initWithHandler:aHandler]; - if (self) { - NSError *error = nil; - self.engine = [[RNCryptorEngine alloc] initWithOperation:kCCDecrypt - settings:theSettings - key:anEncryptionKey - IV:anIV - error:&error]; - if (!self.engine) { - [self cleanupAndNotifyWithError:error]; - self = nil; - return nil; - } - self.HMACLength = 0; - self.settings = theSettings; - } - - return self; -} - -- (RNDecryptor *)initWithSettings:(RNCryptorSettings)theSettings password:(NSString *)aPassword handler:(RNCryptorHandler)aHandler -{ - NSParameterAssert(aPassword != nil); - - self = [super initWithHandler:aHandler]; - if (self) { - self.HMACLength = 0; - self.password = aPassword; - self.settings = theSettings; - } - - return self; -} - -- (RNDecryptor *)initWithEncryptionKey:(NSData *)encryptionKey - HMACKey:(NSData *)HMACKey - handler:(RNCryptorHandler)handler -{ - NSAssert(NO, @"%s -- Cannot be used in OpenSSL mode. An IV or password is required", __func__); - return nil; -} - -- (RNDecryptor *)initWithPassword:(NSString *)password - handler:(RNCryptorHandler)handler -{ - NSAssert(NO, @"%s -- Cannot be used in OpenSSL mode. Settings are required", __func__); - return nil; -} - -+ (NSData *)decryptData:(NSData *)data withPassword:(NSString *)password error:(NSError **)error -{ - NSAssert(NO, @"%s -- Cannot be used in OpenSSL mode. Settings are required", __func__); - return nil; - -} - -+ (NSData *)decryptData:(NSData *)data withEncryptionKey:(NSData *)encryptionKey HMACKey:(NSData *)HMACKey error:(NSError **)error -{ - NSAssert(NO, @"%s -- Cannot be used in OpenSSL mode. Settings are required", __func__); - return nil; -} - -- (void)consumeHeaderFromData:(NSMutableData *)data -{ - RNCryptorSettings settings = self.settings; - if (data.length < [kRNCryptorOpenSSLSaltedString length] + settings.keySettings.saltSize) { - return; - } - - NSString *saltedPrefix = [[NSString alloc] initWithData:[data _RNConsumeToIndex:[kRNCryptorOpenSSLSaltedString length]] encoding:NSUTF8StringEncoding]; - if (![kRNCryptorOpenSSLSaltedString isEqualToString:saltedPrefix]) { - [self cleanupAndNotifyWithError:[NSError errorWithDomain:kRNCryptorErrorDomain - code:kRNCryptorUnknownHeader - userInfo:[NSDictionary dictionaryWithObject:@"Unknown header" /* DNL */ - forKey:NSLocalizedDescriptionKey]]]; - } - - NSData *salt = [data _RNConsumeToIndex:settings.keySettings.saltSize]; - NSData *key = RNOpenSSLCryptorGetKey(self.password, salt, settings.keySettings); - NSData *IV = RNOpenSSLCryptorGetIV(key, self.password, salt, settings.keySettings); - NSError *error = nil; - - self.engine = [[RNCryptorEngine alloc] initWithOperation:kCCDecrypt - settings:settings - key:key - IV:IV - error:&error]; - if (!self.engine) { - [self cleanupAndNotifyWithError:error]; - return; - } -} - -@end \ No newline at end of file diff --git a/RNCryptor/RNOpenSSLEncryptor.h b/RNCryptor/RNOpenSSLEncryptor.h deleted file mode 100644 index f9386915..00000000 --- a/RNCryptor/RNOpenSSLEncryptor.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// RNOpenSSLEncryptor -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#import -#import "RNEncryptor.h" - -@interface RNOpenSSLEncryptor : RNEncryptor -+ (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey IV:(NSData *)IV error:(NSError **)error; -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey IV:(NSData *)anIV handler:(RNCryptorHandler)aHandler; -@end \ No newline at end of file diff --git a/RNCryptor/RNOpenSSLEncryptor.m b/RNCryptor/RNOpenSSLEncryptor.m deleted file mode 100644 index e81f3211..00000000 --- a/RNCryptor/RNOpenSSLEncryptor.m +++ /dev/null @@ -1,122 +0,0 @@ -// -// RNOpenSSLEncryptor -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// For aes-128: -// -// key = MD5(password + salt) -// IV = MD5(Key + password + salt) - -// -// For aes-256: -// -// Hash0 = '' -// Hash1 = MD5(Hash0 + Password + Salt) -// Hash2 = MD5(Hash1 + Password + Salt) -// Hash3 = MD5(Hash2 + Password + Salt) -// Hash4 = MD5(Hash3 + Password + Salt) -// -// Key = Hash1 + Hash2 -// IV = Hash3 + Hash4 -// - -// File Format: -// -// |Salted___||| - -#import "RNOpenSSLEncryptor.h" -#import "RNCryptor+Private.h" -#import "RNCryptorEngine.h" -#import "RNOpenSSLCryptor.h" - -@interface RNOpenSSLEncryptor () -@property (nonatomic, readwrite, strong) NSData *encryptionSalt; -@end - -@implementation RNOpenSSLEncryptor -@synthesize encryptionSalt = _encryptionSalt; - -+ (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey IV:(NSData *)IV error:(NSError **)error -{ - RNEncryptor *cryptor = [[self alloc] initWithSettings:settings encryptionKey:encryptionKey IV:IV handler:^(RNCryptor *c, NSData *d) {}]; - return [self synchronousResultForCryptor:cryptor data:data error:error]; -} - -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey HMACKey:(NSData *)HMACKey handler:(RNCryptorHandler)handler -{ - NSAssert(NO, @"%s -- Cannot be used in OpenSSL mode. An IV or password is required", __func__); - return nil; -} - -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey IV:(NSData *)anIV handler:(RNCryptorHandler)aHandler -{ - self = [super initWithHandler:aHandler]; - if (self) { - NSError *error = nil; - self.engine = [[RNCryptorEngine alloc] initWithOperation:kCCEncrypt - settings:theSettings - key:anEncryptionKey - IV:anIV - error:&error]; - if (!self.engine) { - [self cleanupAndNotifyWithError:error]; - self = nil; - return nil; - } - self.HMACLength = 0; - } - - return self; -} - -- (RNEncryptor *)initWithSettings:(RNCryptorSettings)theSettings password:(NSString *)aPassword handler:(RNCryptorHandler)aHandler -{ - NSParameterAssert(aPassword != nil); - - NSData *encryptionSalt = [[self class] randomDataOfLength:theSettings.keySettings.saltSize]; - NSData *encryptionKey = RNOpenSSLCryptorGetKey(aPassword, encryptionSalt, theSettings.keySettings); - NSData *IV = RNOpenSSLCryptorGetIV(encryptionKey, aPassword, encryptionSalt, theSettings.keySettings); - self = [self initWithSettings:theSettings - encryptionKey:encryptionKey - IV:IV - handler:aHandler]; - if (self) { - self.options |= kRNCryptorOptionHasPassword; - self.encryptionSalt = encryptionSalt; - } - return self; -} - -- (NSData *)header -{ - NSMutableData *headerData = [NSMutableData data]; - if (kRNCryptorOptionHasPassword == (self.options & kRNCryptorOptionHasPassword)) { - [headerData appendData:[kRNCryptorOpenSSLSaltedString dataUsingEncoding:NSUTF8StringEncoding]]; - [headerData appendData:self.encryptionSalt]; - } - return headerData; -} - -@end \ No newline at end of file diff --git a/RNCryptorOSX/RNCryptorOSX-Info.plist b/RNCryptorOSX/RNCryptorOSX-Info.plist index 1061bead..15a450a9 100644 --- a/RNCryptorOSX/RNCryptorOSX-Info.plist +++ b/RNCryptorOSX/RNCryptorOSX-Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - net.robnapier.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/RNCryptorTests/GenVectorTests b/RNCryptorTests/GenVectorTests new file mode 100755 index 00000000..70d19ef1 --- /dev/null +++ b/RNCryptorTests/GenVectorTests @@ -0,0 +1,78 @@ +#!/usr/bin/env ruby + +require 'optparse' +require File.join(File.dirname(__FILE__), '../Spec/vectors', 'vectorparser') + +@test_files = ["v3/kdf", "v3/password", "v3/key", + "v2/kdf", "v2/password", + "v1/kdf", "v1/password", + ] + +@options = {} + +# Returns the text for an NSDictionary assignment from a hash +def NSDictionaryForHash(hash) + "@{\n" + hash.collect { |key, value| %Q( @"#{key}": @"#{value}") }.join(",\n") + "}" +end + +# Output the file header to output stream +def outputHeader(output) + output << <<-HEADER +// Automatically Generated by GenVectorTests +#import "XCTestCase+RNCryptorVectorTests.h" +@interface RNCryptorGeneratedVectorTests : XCTestCase +@end +@implementation RNCryptorGeneratedVectorTests +HEADER +end + +# Output the tests for a given filename to the output stream +def outputTestsForFile(output, name) + name_identifier = name.gsub('/', '_') + VectorParser.new(@options[:vector_directory] + '/' + name).vectors.each do |vector| + output << <<-TEST_CASE + +- (void)test_#{name_identifier}_#{vector["title"].gsub(/[ ()-]+/, '_')} { + [self verify_#{name_identifier}:#{NSDictionaryForHash(vector)}]; +} + +TEST_CASE + + end +end + +# Output the footer to the output stream +def outputFooter(output) + output<< <<-FOOTER +@end +FOOTER +end + +################### +### MAIN +################### +opt_parser = OptionParser.new do |opt| + opt.banner = "Usage: GenVectorTest -o VectorTests.m " + opt.separator "" + opt.on("-o","--output PATH","path to output code") do |output_path| + @options[:output_path] = output_path + end + opt.on("-3", "-3 PATH", "path to v3 directory") do |v3_directory| + @options[:v3_directory] = v3_directory + end +end + +opt_parser.parse! + +raise OptionParser::MissingArgument if @options[:output_path].nil? +raise OptionParser::MissingArgument if ARGV.length != 1 + +@options[:vector_directory] = ARGV[0] + +File.open(@options[:output_path], "w") do |output| + outputHeader(output) + @test_files.each do |file| + outputTestsForFile(output, file) + end + outputFooter(output) +end diff --git a/RNCryptorTests/Generated/RNCryptorGeneratedVectorTests.m b/RNCryptorTests/Generated/RNCryptorGeneratedVectorTests.m new file mode 100644 index 00000000..9fad8fa0 --- /dev/null +++ b/RNCryptorTests/Generated/RNCryptorGeneratedVectorTests.m @@ -0,0 +1,298 @@ +// Automatically Generated by GenVectorTests +#import "XCTestCase+RNCryptorVectorTests.h" +@interface RNCryptorGeneratedVectorTests : XCTestCase +@end +@implementation RNCryptorGeneratedVectorTests + +- (void)test_v3_kdf_One_byte { + [self verify_v3_kdf:@{ + @"title": @"One byte", + @"version": @"3", + @"password": @"a", + @"salt_hex": @"0102030405060708", + @"key_hex": @"fc632b0c a6b23eff 9a9dc3e0 e585167f 5a328916 ed19f835 58be3ba9 828797cd"}]; +} + + +- (void)test_v3_kdf_Short_password { + [self verify_v3_kdf:@{ + @"title": @"Short password", + @"version": @"3", + @"password": @"thepassword", + @"salt_hex": @"0203040506070801", + @"key_hex": @"0ea84f52 52310dc3 e3a7607c 33bfd1eb 580805fb 68293005 da21037c cf499626"}]; +} + + +- (void)test_v3_kdf_Passphrase { + [self verify_v3_kdf:@{ + @"title": @"Passphrase", + @"version": @"3", + @"password": @"this is a bit longer password", + @"salt_hex": @"0304050607080102", + @"key_hex": @"71343acb 1e9675b0 16ac65dc fe5ddac2 e57ed9c3 5565fdbb 2dd6d2ce fe263d5b"}]; +} + + +- (void)test_v3_kdf_Long_passphrase { + [self verify_v3_kdf:@{ + @"title": @"Long passphrase", + @"version": @"3", + @"password": @"$$$it was the epoch of belief, it was the epoch of incredulity; it was the season of Light, it was the season of Darkness; it was the spring of hope, it was the winter of despair; we had everything before us, we had nothing before us; we were all going directly to Heaven, we were all going the other way.", + @"salt_hex": @"0405060708010203", + @"key_hex": @"11b52c50 cbf45be6 a636a314 2b8c30b8 5a624481 4a7d43e3 7457f38d e46c6735"}]; +} + + +- (void)test_v3_kdf_Multibyte { + [self verify_v3_kdf:@{ + @"title": @"Multibyte", + @"version": @"3", + @"password": @"中文密码", + @"salt_hex": @"0506070801020304", + @"key_hex": @"d2fc3237 d4a69668 ca83d969 c2cda1ac 6c368479 2b6644b1 a90b2052 007215dd"}]; +} + + +- (void)test_v3_kdf_Mixed_language { + [self verify_v3_kdf:@{ + @"title": @"Mixed language", + @"version": @"3", + @"password": @"中文密码 with a little English, too.", + @"salt_hex": @"0607080102030405", + @"key_hex": @"46bda5f4 65982a47 40c728bc 14c5de5c c7fc4eea f0aa41bb 9b9e8495 452dafff"}]; +} + + +- (void)test_v3_password_All_fields_empty_or_zero_with_one_byte_password_ { + [self verify_v3_password:@{ + @"title": @"All fields empty or zero (with one-byte password)", + @"version": @"3", + @"password": @"a", + @"enc_salt_hex": @"0000000000000000", + @"hmac_salt_hex": @"0000000000000000", + @"iv_hex": @"00000000000000000000000000000000", + @"plaintext_hex": @"", + @"ciphertext_hex": @"03010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000b303 9be31cd7 ece5e754 f5c8da17 00366631 3ae8a89d dcf8e3cb 41fdc130 b2329dbe 07d6f4d3 2c34e050 c8bd7e93 3b12"}]; +} + + +- (void)test_v3_password_One_byte { + [self verify_v3_password:@{ + @"title": @"One byte", + @"version": @"3", + @"password": @"thepassword", + @"enc_salt_hex": @"0001020304050607", + @"hmac_salt_hex": @"0102030405060708", + @"iv_hex": @"02030405060708090a0b0c0d0e0f0001", + @"plaintext_hex": @"01", + @"ciphertext_hex": @"03010001 02030405 06070102 03040506 07080203 04050607 08090a0b 0c0d0e0f 0001a1f8 730e0bf4 80eb7b70 f690abf2 1e029514 164ad3c4 74a51b30 c7eaa1ca 545b7de3 de5b010a cbad0a9a 13857df6 96a8"}]; +} + + +- (void)test_v3_password_Exactly_one_block { + [self verify_v3_password:@{ + @"title": @"Exactly one block", + @"version": @"3", + @"password": @"thepassword", + @"enc_salt_hex": @"0102030405060700", + @"hmac_salt_hex": @"0203040506070801", + @"iv_hex": @"030405060708090a0b0c0d0e0f000102", + @"plaintext_hex": @"0123456789abcdef", + @"ciphertext_hex": @"03010102 03040506 07000203 04050607 08010304 05060708 090a0b0c 0d0e0f00 01020e43 7fe80930 9c03fd53 a475131e 9a1978b8 eaef576f 60adb8ce 2320849b a32d7429 00438ba8 97d22210 c76c35c8 49df"}]; +} + + +- (void)test_v3_password_More_than_one_block { + [self verify_v3_password:@{ + @"title": @"More than one block", + @"version": @"3", + @"password": @"thepassword", + @"enc_salt_hex": @"0203040506070001", + @"hmac_salt_hex": @"0304050607080102", + @"iv_hex": @"0405060708090a0b0c0d0e0f00010203", + @"plaintext_hex": @"0123456789abcdef 01234567", + @"ciphertext_hex": @"03010203 04050607 00010304 05060708 01020405 06070809 0a0b0c0d 0e0f0001 0203e01b bda5df2c a8adace3 8f6c588d 291e03f9 51b78d34 17bc2816 581dc6b7 67f1a2e5 7597512b 18e1638f 21235fa5 928c"}]; +} + + +- (void)test_v3_password_Multibyte_password { + [self verify_v3_password:@{ + @"title": @"Multibyte password", + @"version": @"3", + @"password": @"中文密码", + @"enc_salt_hex": @"0304050607000102", + @"hmac_salt_hex": @"0405060708010203", + @"iv_hex": @"05060708090a0b0c0d0e0f0001020304", + @"plaintext_hex": @"23456789abcdef 0123456701", + @"ciphertext_hex": @"03010304 05060700 01020405 06070801 02030506 0708090a 0b0c0d0e 0f000102 03048a9e 08bdec1c 4bfe13e8 1fb85f00 9ab3ddb9 1387e809 c4ad86d9 e8a60145 57716657 bd317d4b b6a76446 15b3de40 2341"}]; +} + + +- (void)test_v3_password_Longer_text_and_password { + [self verify_v3_password:@{ + @"title": @"Longer text and password", + @"version": @"3", + @"password": @"It was the best of times, it was the worst of times; it was the age of wisdom, it was the age of foolishness;", + @"enc_salt_hex": @"0405060700010203", + @"hmac_salt_hex": @"0506070801020304", + @"iv_hex": @"060708090a0b0c0d0e0f000102030405", + @"plaintext_hex": @"69 74 20 77 61 73 20 74 68 65 20 65 70 6f 63 68 20 6f 66 20 62 65 6c 69 65 66 2c 20 69 74 20 77 61 73 20 74 68 65 20 65 70 6f 63 68 20 6f 66 20 69 6e 63 72 65 64 75 6c 69 74 79 3b 20 69 74 20 77 61 73 20 74 68 65 20 73 65 61 73 6f 6e 20 6f 66 20 4c 69 67 68 74 2c 20 69 74 20 77 61 73 20 74 68 65 20 73 65 61 73 6f 6e 20 6f 66 20 44 61 72 6b 6e 65 73 73 3b 20 69 74 20 77 61 73 20 74 68 65 20 73 70 72 69 6e 67 20 6f 66 20 68 6f 70 65 2c 20 69 74 20 77 61 73 20 74 68 65 20 77 69 6e 74 65 72 20 6f 66 20 64 65 73 70 61 69 72 3b 20 77 65 20 68 61 64 20 65 76 65 72 79 74 68 69 6e 67 20 62 65 66 6f 72 65 20 75 73 2c 20 77 65 20 68 61 64 20 6e 6f 74 68 69 6e 67 20 62 65 66 6f 72 65 20 75 73 3b 20 77 65 20 77 65 72 65 20 61 6c 6c 20 67 6f 69 6e 67 20 64 69 72 65 63 74 6c 79 20 74 6f 20 48 65 61 76 65 6e 2c 20 77 65 20 77 65 72 65 20 61 6c 6c 20 67 6f 69 6e 67 20 74 68 65 20 6f 74 68 65 72 20 77 61 79 2e 0a 0a", + @"ciphertext_hex": @"03010405 06070001 02030506 07080102 03040607 08090a0b 0c0d0e0f 00010203 0405d564 c7a99da9 21a6e7c4 078a8264 1d954795 51283167 a2c81f31 ab80c9d7 d8beb770 111decd3 e3d29bbd f7ebbfc5 f10ac87e 7e55bfb5 a7f487bc d3983570 5e83b9c0 49c6d695 2be011f8 ddb1a14f c0c92573 8de017e6 2b1d621c cdb75f29 37d0a1a7 0e44d843 b9c61037 dee2998b 2bbd740b 910232ee a7196116 8838f699 5b996417 3b34c0bc d311a2c8 7e271630 928bae30 1a8f4703 ac2ae469 9f3c285a bf1c55ac 324b073a 958ae52e e8c3bd68 f919c09e b1cd2814 2a1996a9 e6cbff5f 4f4e1dba 07d29ff6 6860db98 95a48233 140ca249 419d6304 6448db1b 0f4252a6 e4edb947 fd0071d1 e52bc156 00622fa5 48a67739 63618150 797a8a80 e592446d f5926d0b fd32b544 b796f335 9567394f 77e7b171 b2f9bc5f 2caf7a0f ac0da7d0 4d6a8674 4d6e06d0 2fbe15d0 f580a1d5 bd16ad91 34800361 1358dcb4 ac999095 5f6cbbbf b185941d 4b4b71ce 7f9ba6ef c1270b78 08838b6c 7b7ef17e 8db919b3 4fac"}]; +} + + +- (void)test_v3_key_All_fields_empty_or_zero { + [self verify_v3_key:@{ + @"title": @"All fields empty or zero", + @"version": @"3", + @"enc_key_hex": @"0000000000000000000000000000000000000000000000000000000000000000", + @"hmac_key_hex": @"0000000000000000000000000000000000000000000000000000000000000000", + @"iv_hex": @"00000000000000000000000000000000", + @"plaintext_hex": @"", + @"ciphertext_hex": @"03000000 00000000 00000000 00000000 00001f78 8fe6d86c 31754969 7fbf0c07 fa436384 ac0ef35b 860b2ddb 2aba2fff 816b1fb3 a9c180f7 b43650ae c0d2b5f8 8e33"}]; +} + + +- (void)test_v3_key_One_byte { + [self verify_v3_key:@{ + @"title": @"One byte", + @"version": @"3", + @"enc_key_hex": @"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", + @"hmac_key_hex": @"0102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", + @"iv_hex": @"02030405060708090a0b0c0d0e0f0001", + @"plaintext_hex": @"01", + @"ciphertext_hex": @"03000203 04050607 08090a0b 0c0d0e0f 0001981b 22e7a644 8118d695 bd654f72 e9d6ed75 ec14ae2a a067eed2 a98a56e0 993dfe22 ab5887b3 f6e3cdd4 0767f519 5eb5"}]; +} + + +- (void)test_v3_key_Exactly_one_block { + [self verify_v3_key:@{ + @"title": @"Exactly one block", + @"version": @"3", + @"enc_key_hex": @"0102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", + @"hmac_key_hex": @"02030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f0001", + @"iv_hex": @"030405060708090a0b0c0d0e0f000102", + @"plaintext_hex": @"000102030405060708090a0b0c0d0e0f", + @"ciphertext_hex": @"03000304 05060708 090a0b0c 0d0e0f00 0102d2b1 77d61878 1829f564 53f739a2 d4f729f9 2b1a9c6c 50837864 74e16a22 c60f92b0 73454f79 76cdda04 3e09b117 66de05ff e05bc1dc a9522ea6 6e64ad25 bbbc"}]; +} + + +- (void)test_v3_key_More_than_one_block { + [self verify_v3_key:@{ + @"title": @"More than one block", + @"version": @"3", + @"enc_key_hex": @"02030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f0001", + @"hmac_key_hex": @"030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102", + @"iv_hex": @"0405060708090a0b0c0d0e0f00010203", + @"plaintext_hex": @"000102030405060708090a0b0c0d0e0f 000102030405060708", + @"ciphertext_hex": @"03000405 06070809 0a0b0c0d 0e0f0001 02034c9b 98b425f1 d732644c b311278d 858e3d18 2a0789b8 6af7f741 34b6a27e 9d938617 741c0fb8 aaf094b3 b5b26f50 5da7bf19 13f6c17e 70273977 ae51323b 6f09"}]; +} + + +- (void)test_v2_kdf_One_byte { + [self verify_v2_kdf:@{ + @"title": @"One byte", + @"version": @"2", + @"password": @"a", + @"salt_hex": @"0102030405060708", + @"key_hex": @"fc632b0c a6b23eff 9a9dc3e0 e585167f 5a328916 ed19f835 58be3ba9 828797cd"}]; +} + + +- (void)test_v2_kdf_Short_password { + [self verify_v2_kdf:@{ + @"title": @"Short password", + @"version": @"2", + @"password": @"thepassword", + @"salt_hex": @"0203040506070801", + @"key_hex": @"0ea84f52 52310dc3 e3a7607c 33bfd1eb 580805fb 68293005 da21037c cf499626"}]; +} + + +- (void)test_v2_kdf_Passphrase { + [self verify_v2_kdf:@{ + @"title": @"Passphrase", + @"version": @"2", + @"password": @"this is a bit longer password", + @"salt_hex": @"0304050607080102", + @"key_hex": @"71343acb 1e9675b0 16ac65dc fe5ddac2 e57ed9c3 5565fdbb 2dd6d2ce fe263d5b"}]; +} + + +- (void)test_v2_kdf_Long_passphrase { + [self verify_v2_kdf:@{ + @"title": @"Long passphrase", + @"version": @"2", + @"password": @"$$$it was the epoch of belief, it was the epoch of incredulity; it was the season of Light, it was the season of Darkness; it was the spring of hope, it was the winter of despair; we had everything before us, we had nothing before us; we were all going directly to Heaven, we were all going the other way.", + @"salt_hex": @"0405060708010203", + @"key_hex": @"11b52c50 cbf45be6 a636a314 2b8c30b8 5a624481 4a7d43e3 7457f38d e46c6735"}]; +} + + +- (void)test_v2_password_Multi_block { + [self verify_v2_password:@{ + @"title": @"Multi-block", + @"version": @"2", + @"password": @"password", + @"enc_salt_hex": @"9707 6dc6 61b6 e0ce", + @"hmac_salt_hex": @"9da3 bb43 d95b cd45", + @"iv_hex": @"ee39 6d39 e342 ffdb 679b 270d cd9c 557c", + @"plaintext_hex": @"546869732069732061206c6f6e676572207465737420766563746f722069 6e74656e64656420746f206265206c6f6e676572207468616e206f6e6520 626c6f636b2e", + @"ciphertext_hex": @"020197076dc661b6e0ce9da3bb43d95bcd45ee396d39e342ffdb679b270d cd9c557c37055fffcc1b663b1e6b8c5694dbb96d97a3ac0fa3f355db6668 c5a8a2a06f10056ce92384a618a35bf0fa9eb612b0b4fa72f749f76e2f72 8c16574dc2f15b7cec1786d291c2135f932ddc5a34d9eafd6b45f99491ac 23c34299af0be68a43e6e8113bb748fbc19bcad638ea79b07309"}]; +} + + +- (void)test_v1_kdf_One_byte { + [self verify_v1_kdf:@{ + @"title": @"One byte", + @"version": @"1", + @"password": @"a", + @"salt_hex": @"0102030405060708", + @"key_hex": @"fc632b0c a6b23eff 9a9dc3e0 e585167f 5a328916 ed19f835 58be3ba9 828797cd"}]; +} + + +- (void)test_v1_kdf_Short_password { + [self verify_v1_kdf:@{ + @"title": @"Short password", + @"version": @"1", + @"password": @"thepassword", + @"salt_hex": @"0203040506070801", + @"key_hex": @"0ea84f52 52310dc3 e3a7607c 33bfd1eb 580805fb 68293005 da21037c cf499626"}]; +} + + +- (void)test_v1_kdf_Passphrase { + [self verify_v1_kdf:@{ + @"title": @"Passphrase", + @"version": @"1", + @"password": @"this is a bit longer password", + @"salt_hex": @"0304050607080102", + @"key_hex": @"71343acb 1e9675b0 16ac65dc fe5ddac2 e57ed9c3 5565fdbb 2dd6d2ce fe263d5b"}]; +} + + +- (void)test_v1_kdf_Long_passphrase { + [self verify_v1_kdf:@{ + @"title": @"Long passphrase", + @"version": @"1", + @"password": @"$$$it was the epoch of belief, it was the epoch of incredulity; it was the season of Light, it was the season of Darkness; it was the spring of hope, it was the winter of despair; we had everything before us, we had nothing before us; we were all going directly to Heaven, we were all going the other way.", + @"salt_hex": @"0405060708010203", + @"key_hex": @"11b52c50 cbf45be6 a636a314 2b8c30b8 5a624481 4a7d43e3 7457f38d e46c6735"}]; +} + + +- (void)test_v1_password_Multi_block { + [self verify_v1_password:@{ + @"title": @"Multi-block", + @"version": @"1", + @"password": @"password", + @"enc_salt_hex": @"9707 6dc6 61b6 e0ce", + @"hmac_salt_hex": @"9da3 bb43 d95b cd45", + @"iv_hex": @"ee39 6d39 e342 ffdb 679b 270d cd9c 557c", + @"plaintext_hex": @"546869732069732061206c6f6e676572207465737420766563746f722069 6e74656e64656420746f206265206c6f6e676572207468616e206f6e6520 626c6f636b2e", + @"ciphertext_hex": @"0101d5e9b0eeefa3336d7578c1f9babe4b5de9ecf9598c104ae1e080ec71 e0cabad22204d8d0dc5bf77203fa7e46465d09136cd4a194aadf2b5593d5 f9122aa13b27dc7afaca7ca1548e046a92298ee884c014b5b4a55503be28 852ba1a2750208fd5f0e410e7c1eb969c3990c621b3b73a65715de4d9ff5 6e159ee7625e852517b135dbccef0b9460350a04cd6e3d10e925"}]; +} + +@end diff --git a/RNCryptorTests/README.md b/RNCryptorTests/README.md new file mode 100644 index 00000000..2009fb20 --- /dev/null +++ b/RNCryptorTests/README.md @@ -0,0 +1,3 @@ +openssl.enc: + echo Test data | openssl enc -aes-256-cbc -out test.enc -k Passw0rd + diff --git a/RNCryptorTests/RNCryptorTestHelpers.h b/RNCryptorTests/RNCryptorTestHelpers.h new file mode 100644 index 00000000..0410468b --- /dev/null +++ b/RNCryptorTests/RNCryptorTestHelpers.h @@ -0,0 +1,11 @@ +// +// RNCryptorTestHelpers.h +// RNCryptor +// +// Created by Rob Napier on 12/12/13. +// Copyright (c) 2013 Rob Napier. All rights reserved. +// + +#import + +NSString * CreateTemporaryFilePath(void); diff --git a/RNCryptorTests/RNCryptorTestHelpers.m b/RNCryptorTests/RNCryptorTestHelpers.m new file mode 100644 index 00000000..ee8cb0cd --- /dev/null +++ b/RNCryptorTests/RNCryptorTestHelpers.m @@ -0,0 +1,29 @@ +// +// RNCryptorTestHelpers.m +// RNCryptor +// +// Created by Rob Napier on 12/12/13. +// Copyright (c) 2013 Rob Napier. All rights reserved. +// + +#import "RNCryptorTestHelpers.h" + +NSString * CreateTemporaryFilePath() +{ + // Thanks to Matt Gallagher + NSString *tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"RNCryptorTest.XXXXXX"]; + const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation]; + char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1); + strcpy(tempFileNameCString, tempFileTemplateCString); + int fileDescriptor = mkstemp(tempFileNameCString); + + NSCAssert(fileDescriptor >= 0, @"Failed to create temporary file"); + + NSString *tempFileName = + [[NSFileManager defaultManager] + stringWithFileSystemRepresentation:tempFileNameCString + length:strlen(tempFileNameCString)]; + + free(tempFileNameCString); + return tempFileName; +} \ No newline at end of file diff --git a/RNCryptorTests/RNCryptorTests-Info.plist b/RNCryptorTests/RNCryptorTests-Info.plist index 4637133b..169b6f71 100644 --- a/RNCryptorTests/RNCryptorTests-Info.plist +++ b/RNCryptorTests/RNCryptorTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - net.robnapier.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/RNCryptorTests/RNCryptorTests.h b/RNCryptorTests/RNCryptorTests.h deleted file mode 100644 index 9ffadf60..00000000 --- a/RNCryptorTests/RNCryptorTests.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// RNCryptTests.h -// -// Copyright (c) 2012 Rob Napier -// -// This code is licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#import - -@interface RNCryptorTests : SenTestCase - -@end diff --git a/RNCryptorTests/RNCryptorTests.m b/RNCryptorTests/RNCryptorTests.m index 87ea3988..91634d82 100644 --- a/RNCryptorTests/RNCryptorTests.m +++ b/RNCryptorTests/RNCryptorTests.m @@ -24,22 +24,24 @@ // DEALINGS IN THE SOFTWARE. // -#import "RNCryptorTests.h" +#import + #import "RNEncryptor.h" #import "RNDecryptor.h" -#import "RNOpenSSLEncryptor.h" -#import "RNOpenSSLDecryptor.h" NSString *const kGoodPassword = @"Passw0rd!"; NSString *const kBadPassword = @"NotThePassword"; -@interface RNCryptorTests () // +@interface RNCryptorTests : XCTestCase @property (nonatomic, readwrite, assign) BOOL isTestRunning; @property (nonatomic, readwrite, strong) RNEncryptor *encryptor; @end -@implementation RNCryptorTests +@interface NSData (RNCryptor_ConsistentCompare) +- (BOOL)rnc_isEqualInConsistentTime:(NSData *)otherData; +@end +@implementation RNCryptorTests - (void)setUp { @@ -66,8 +68,8 @@ - (void) testAsyncDecrypt { password:kGoodPassword error:&error]; - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSInputStream *inputStream = [NSInputStream inputStreamWithData:encryptedData]; [inputStream open]; @@ -84,26 +86,26 @@ - (void) testAsyncDecrypt { __block NSMutableData *buffer = [NSMutableData dataWithLength:blockSize]; dispatch_block_t readStreamBlock = ^{ - [buffer setLength:blockSize]; - NSInteger bytesRead = [inputStream read:[buffer mutableBytes] maxLength:blockSize]; - if (bytesRead < 0) { - STFail(@"Error reading block:%@", inputStream.streamError); - [inputStream close]; - dispatch_semaphore_signal(sem); - } - else if (bytesRead == 0) { - [inputStream close]; - [decryptor finish]; - } - else { - [buffer setLength:bytesRead]; - [decryptor addData:buffer]; - NSLog(@"Sent %ld bytes to decryptor", (unsigned long)bytesRead); + @autoreleasepool { + [buffer setLength:blockSize]; + NSInteger bytesRead = [inputStream read:[buffer mutableBytes] maxLength:blockSize]; + if (bytesRead < 0) { + XCTFail(@"Error reading block:%@", inputStream.streamError); + [inputStream close]; + dispatch_semaphore_signal(sem); + } + else if (bytesRead == 0) { + [inputStream close]; + [decryptor finish]; + } + else { + [buffer setLength:bytesRead]; + [decryptor addData:buffer]; + } } }; decryptor = [[RNDecryptor alloc] initWithPassword:kGoodPassword handler:^(RNCryptor *cryptor, NSData *data) { - NSLog(@"Received %d bytes", data.length); [outputStream write:data.bytes maxLength:data.length]; if (cryptor.isFinished) { [outputStream close]; @@ -111,20 +113,21 @@ - (void) testAsyncDecrypt { } else { readStreamBlock(); - } }]; + } + }]; readStreamBlock(); long timedout = dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); - STAssertFalse(timedout, @"Test timed out."); - STAssertNil(decryptionError, @"Decrypt error: %@", decryptionError); + XCTAssertFalse(timedout, @"Test timed out."); + XCTAssertNil(decryptionError, @"Decrypt error: %@", decryptionError); //Retrieve the decrypted data NSData *decryptedData = [outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; - STAssertTrue([decryptedData length] > 0, @"Failed to decrypt."); + XCTAssertTrue([decryptedData length] > 0, @"Failed to decrypt."); - STAssertEqualObjects(decryptedData, plaintext, @"Incorrect decryption."); + XCTAssertEqualObjects(decryptedData, plaintext, @"Incorrect decryption."); } @@ -138,30 +141,27 @@ - (void)testSimple password:kGoodPassword error:&error]; - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:kGoodPassword error:&decryptionError]; - STAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); - STAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); + XCTAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); + XCTAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { - NSLog(@"didReciveData"); [self.encryptor addData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - NSLog(@"didFailWithError:%@", error); self.isTestRunning = NO; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - NSLog(@"didFinishLoading"); [self.encryptor finish]; } @@ -170,11 +170,11 @@ - (void)testAsync NSURL *testURL = [NSURL URLWithString:@"http://robnapier.net/favicon.ico"]; NSError *downloadError = nil; NSData *plaintext = [NSData dataWithContentsOfURL:testURL options:0 error:&downloadError]; - STAssertNotNil(plaintext, @"Couldn't download: %@", downloadError); + XCTAssertNotNil(plaintext, @"Couldn't download: %@", downloadError); NSURLRequest *request = [NSURLRequest requestWithURL:testURL]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; - NSLog(@"Started connection:%@", connection); + [connection start]; self.isTestRunning = YES; __block NSMutableData *encryptedData = [NSMutableData data]; @@ -182,7 +182,6 @@ - (void)testAsync self.encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings password:kGoodPassword handler:^(RNCryptor *cryptor, NSData *data) { - NSLog(@"handler"); [encryptedData appendData:data]; if (cryptor.isFinished) { encryptionError = cryptor.error; @@ -196,14 +195,14 @@ - (void)testAsync beforeDate:timeout]; } while (self.isTestRunning); - STAssertFalse(self.isTestRunning, @"Test timed out."); - STAssertNil(encryptionError, @"Encrypt error: %@", encryptionError); - STAssertTrue([encryptedData length] > 0, @"Failed to encrypt."); + XCTAssertFalse(self.isTestRunning, @"Test timed out."); + XCTAssertNil(encryptionError, @"Encrypt error: %@", encryptionError); + XCTAssertTrue([encryptedData length] > 0, @"Failed to encrypt."); NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:kGoodPassword error:&decryptionError]; - STAssertNil(decryptionError, @"decryption error:%@", decryptionError); - STAssertEqualObjects(plaintext, decryptedData, @"Bad decryption"); + XCTAssertNil(decryptionError, @"decryption error:%@", decryptionError); + XCTAssertEqualObjects(plaintext, decryptedData, @"Bad decryption"); } - (void)testSimpleFail @@ -216,13 +215,13 @@ - (void)testSimpleFail password:kGoodPassword error:&error]; - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:kBadPassword error:&decryptionError]; - STAssertNotNil(decryptionError, @"Should have received error decrypting:%@", decryptionError); - STAssertNil(decryptedData, @"Decryption should be nil: %@", decryptedData); + XCTAssertNotNil(decryptionError, @"Should have received error decrypting:%@", decryptionError); + XCTAssertNil(decryptedData, @"Decryption should be nil: %@", decryptedData); } - (void)testCorruption @@ -235,16 +234,16 @@ - (void)testCorruption password:kGoodPassword error:&error]; - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSMutableData *corruptData = [encryptedData mutableCopy]; [corruptData replaceBytesInRange:NSMakeRange(100, 100) withBytes:[[RNCryptor randomDataOfLength:100] bytes]]; NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:corruptData withPassword:kGoodPassword error:&decryptionError]; - STAssertNil(decryptedData, @"Decryption should be nil: %@", decryptedData); - STAssertEquals([decryptionError code], (NSInteger)kRNCryptorHMACMismatch, @"Should have received kRNCryptorHMACMismatch"); + XCTAssertNil(decryptedData, @"Decryption should be nil: %@", decryptedData); + XCTAssertEqual([decryptionError code], (NSInteger)kRNCryptorHMACMismatch, @"Should have received kRNCryptorHMACMismatch"); } - (void)testBadHeader @@ -257,8 +256,8 @@ - (void)testBadHeader [encrypted replaceBytesInRange:NSMakeRange(0, 1) withBytes:&firstByte]; NSData *decrypted = [RNDecryptor decryptData:encrypted withPassword:kGoodPassword error:&error]; - STAssertNil(decrypted, @"Decrypt should have failed"); - STAssertEquals([error code], (NSInteger)kRNCryptorUnknownHeader, @"Wrong error code:%d", [error code]); + XCTAssertNil(decrypted, @"Decrypt should have failed"); + XCTAssertEqual([error code], (NSInteger)kRNCryptorUnknownHeader, @"Wrong error code:%ld", (long)[error code]); } - (void)testActuallyEncrypting @@ -268,7 +267,7 @@ - (void)testActuallyEncrypting NSData *encrypted = [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:kGoodPassword error:&error]; NSRange found = [encrypted rangeOfData:data options:0 range:NSMakeRange(0, encrypted.length)]; - STAssertEquals(found.location, (NSUInteger)NSNotFound, @"Data is not encrypted"); + XCTAssertEqual(found.location, (NSUInteger)NSNotFound, @"Data is not encrypted"); } - (void)testBackground @@ -285,13 +284,13 @@ - (void)testBackground error:&error]; }); - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:kGoodPassword error:&decryptionError]; - STAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); - STAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); + XCTAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); + XCTAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); } - (void)testKey @@ -307,125 +306,78 @@ - (void)testKey HMACKey:HMACKey error:&error]; - STAssertNil(error, @"Encryption error:%@", error); - STAssertNotNil(encryptedData, @"Data did not encrypt."); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); NSError *decryptionError = nil; NSData *decryptedData = [RNDecryptor decryptData:encryptedData withEncryptionKey:encryptionKey HMACKey:HMACKey error:&decryptionError]; - STAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); - STAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); + XCTAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); + XCTAssertEqualObjects(decryptedData, data, @"Incorrect decryption."); } -// echo Test data | openssl enc -aes-256-cbc -out test.enc -k Passw0rd - -static NSString *const kOpenSSLString = @"Test data\n"; -static NSString *const kOpenSSLPath = @"test.enc"; -static NSString *const kOpenSSLPassword = @"Passw0rd"; - -- (void)testOpenSSLEncrypt -{ - NSError *error = nil; - - NSData *encryptedData = [RNOpenSSLEncryptor encryptData:[kOpenSSLString dataUsingEncoding:NSUTF8StringEncoding] - withSettings:kRNCryptorAES256Settings - password:kOpenSSLPassword - error:&error]; - STAssertNotNil(encryptedData, @"Did not encrypt"); - STAssertNil(error, @"Error:%@", error); +// Issue #77: KeyForPassword() broken for multi-byte passwords (UTF-8) +- (void)testMultibytePasswordTruncation { + NSData *data = [RNCryptor randomDataOfLength:1024]; + NSString *password = @"中文密码"; // 4 characters, 8 bytes => uses first 2 characters + NSString *truncatedPassword = @"中文xx"; // 4 characters, 6 bytes => uses first 2 characters - NSString *encryptedFile = [self temporaryFilePath]; - NSString *decryptedFile = [self temporaryFilePath]; - [encryptedData writeToFile:encryptedFile atomically:NO]; + NSError *error; + NSData *encryptedData = [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:password error:&error]; - NSString *cmd = [NSString stringWithFormat:@"/usr/bin/openssl enc -d -aes-256-cbc -k %@ -in %@ -out %@", kOpenSSLPassword, encryptedFile, decryptedFile]; - STAssertEquals(system([cmd UTF8String]), 0, @"System call failed"); + XCTAssertNil(error, @"Encryption error:%@", error); + XCTAssertNotNil(encryptedData, @"Data did not encrypt."); - NSString *decryptedString = [NSString stringWithContentsOfFile:decryptedFile encoding:NSUTF8StringEncoding error:&error]; - STAssertEqualObjects(decryptedString, kOpenSSLString, @"Decryption doesn't match: %@", error); + NSError *decryptionError = nil; + NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:truncatedPassword error:&decryptionError]; + XCTAssertNil(decryptedData, @"Decryption should be nil: %@", decryptedData); + XCTAssertEqual([decryptionError code], (NSInteger)kRNCryptorHMACMismatch, @"Should have received kRNCryptorHMACMismatch"); } -- (void)testOpenSSLDecrypt -{ - NSData *encryptedData = [NSData dataWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:kOpenSSLPath ofType:nil]]; +// Issue #77: KeyForPassword() broken for multi-byte passwords (UTF-8) +- (void)testReadVersion2PasswordTruncation { + NSString *plaintext = @"Attack at dawn"; + NSString *password = @"中文密码"; + NSData *v2EncryptionWithPasswordTrunction = + [[NSData alloc] initWithBase64EncodedString:@"AgHOKe1rygDPDDk5DBInKERD85Ezo1EAU5uj+PyEz22o2dtFAjPyaJhY3jW0BXD4W9L4GnAhiscr8PKZ+zOzWDbTFB3/6alv2LWQ1TCG4cpT0g==" options:0]; - NSError *error = nil; - NSData *decryptedData = [RNOpenSSLDecryptor decryptData:encryptedData - withSettings:kRNCryptorAES256Settings - password:kOpenSSLPassword - error:&error]; - STAssertNotNil(decryptedData, @"Did not decrypt"); - STAssertNil(error, @"Error:%@", error); - - NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]; - STAssertEqualObjects(decryptedString, kOpenSSLString, @"Decrypted data does not match"); + NSError *decryptionError = nil; + NSData *decryptedData = [RNDecryptor decryptData:v2EncryptionWithPasswordTrunction withPassword:password error:&decryptionError]; + XCTAssertNil(decryptionError, @"Error decrypting:%@", decryptionError); + XCTAssertEqualObjects(decryptedData, [plaintext dataUsingEncoding:NSUTF8StringEncoding], @"Incorrect decryption."); } -- (void)testOpenSSLDecryptStream { - NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:kOpenSSLPath ofType:nil]; - - NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:filePath]; - [inputStream open]; - - __block NSOutputStream *outputStream = [[NSOutputStream alloc] initToMemory]; - __block NSError *decryptionError = nil; - [outputStream open]; - - __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); +// Issue #24: Crash on 0-length input +- (void)testZeroLengthInput { + NSData *data = [NSData data]; - size_t blockSize = 1024; + NSError *encryptionError; + NSData *encryptedData = [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:kGoodPassword error:&encryptionError]; - __block RNDecryptor *decryptor; - __block NSMutableData *buffer = [NSMutableData dataWithLength:blockSize]; - - - dispatch_block_t readStreamBlock = ^{ - [buffer setLength:blockSize]; - NSInteger bytesRead = [inputStream read:[buffer mutableBytes] maxLength:blockSize]; - if (bytesRead < 0) { - STFail(@"Error reading block:%@", inputStream.streamError); - [inputStream close]; - dispatch_semaphore_signal(sem); - } - else if (bytesRead == 0) { - [inputStream close]; - [decryptor finish]; - } - else { - [buffer setLength:bytesRead]; - [decryptor addData:buffer]; - NSLog(@"Sent %ld bytes to decryptor", (unsigned long)bytesRead); - } - }; + XCTAssertNil(encryptionError, @"Error while encrypting: %@", encryptionError); + XCTAssertNotNil(encryptedData, @"Failed to encrypt: %@", encryptionError); - decryptor = [[RNOpenSSLDecryptor alloc] initWithSettings:kRNCryptorAES256Settings - password:kOpenSSLPassword - handler:^(RNCryptor *cryptor, NSData *data) { - NSLog(@"Received %d bytes", data.length); - if (data.length > 0) { - [outputStream write:data.bytes maxLength:data.length]; - } - if (cryptor.isFinished) { - [outputStream close]; - dispatch_semaphore_signal(sem); - } - else { - readStreamBlock(); - } - }]; + NSError *decryptionError; + NSData *decryptedData = [RNDecryptor decryptData:encryptedData withPassword:kGoodPassword error:&decryptionError]; - readStreamBlock(); - - long timedout = dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); - - STAssertFalse(timedout, @"Test timed out."); - STAssertNil(decryptionError, @"Decrypt error: %@", decryptionError); - - //Retrieve the decrypted data - NSData *decryptedData = [outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; - STAssertTrue([decryptedData length] > 0, @"Failed to decrypt."); + XCTAssertNil(decryptionError, @"Error while decrypting: %@", decryptionError); + XCTAssertEqualObjects(decryptedData, data, @"Failed to decrypt."); +} - NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]; - STAssertEqualObjects(decryptedString, kOpenSSLString, @"Decrypted data does not match"); +- (void)testEqualInConsistentTime +{ + NSData *data = [RNCryptor randomDataOfLength:101]; + NSData *data2 = [RNCryptor randomDataOfLength:102]; + + XCTAssertFalse([data rnc_isEqualInConsistentTime:nil]); + XCTAssertFalse([data rnc_isEqualInConsistentTime:[NSData data]]); + XCTAssertFalse([data rnc_isEqualInConsistentTime:data2]); + XCTAssertTrue([data rnc_isEqualInConsistentTime:data]); + + /* There was a bug where two datas whose length differed by a multiple of 256 could return YES */ + NSData *data256 = [RNCryptor randomDataOfLength:256]; + NSMutableData *data512 = [data256 mutableCopy]; + [data512 appendData:data256]; + XCTAssertFalse([data256 rnc_isEqualInConsistentTime:data512]); } // @@ -622,24 +574,4 @@ - (void)testOpenSSLDecryptStream { // [[NSFileManager defaultManager] removeItemAtURL:decryptedURL error:&error]; //} -- (NSString *)temporaryFilePath -{ - // Thanks to Matt Gallagher - NSString *tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"RNCryptorTest.XXXXXX"]; - const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation]; - char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1); - strcpy(tempFileNameCString, tempFileTemplateCString); - int fileDescriptor = mkstemp(tempFileNameCString); - - NSAssert(fileDescriptor >= 0, @"Failed to create temporary file"); - - NSString *tempFileName = - [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:tempFileNameCString - length:strlen(tempFileNameCString)]; - - free(tempFileNameCString); - return tempFileName; -} - @end diff --git a/RNCryptorTests/XCTestCase+RNCryptorVectorTests.h b/RNCryptorTests/XCTestCase+RNCryptorVectorTests.h new file mode 100644 index 00000000..6d817646 --- /dev/null +++ b/RNCryptorTests/XCTestCase+RNCryptorVectorTests.h @@ -0,0 +1,28 @@ +// +// RNCryptorVectorTests.h +// RNCryptor +// +// Created by Rob Napier on 1/9/14. +// Copyright (c) 2014 Rob Napier. All rights reserved. +// + +#import + +#import "RNEncryptor.h" +#import "RNDecryptor.h" + +// Entry points for auto-generated test cases from GenVectorTests +// Are in the form verify_{filename} + +@interface XCTestCase (RNCryptorVectorTests) +- (void)verify_v3_kdf:(NSDictionary *)vector; +- (void)verify_v3_password:(NSDictionary *)vector; +- (void)verify_v3_key:(NSDictionary *)vector; + +- (void)verify_v2_kdf:(NSDictionary *)vector; +- (void)verify_v2_password:(NSDictionary *)vector; + +- (void)verify_v1_kdf:(NSDictionary *)vector; +- (void)verify_v1_password:(NSDictionary *)vector; + +@end diff --git a/RNCryptorTests/XCTestCase+RNCryptorVectorTests.m b/RNCryptorTests/XCTestCase+RNCryptorVectorTests.m new file mode 100644 index 00000000..d23babb6 --- /dev/null +++ b/RNCryptorTests/XCTestCase+RNCryptorVectorTests.m @@ -0,0 +1,135 @@ +// +// RNCryptorVectorTests.m +// RNCryptor +// +// Created by Rob Napier on 1/9/14. +// Copyright (c) 2014 Rob Napier. All rights reserved. +// + +#import "XCTestCase+RNCryptorVectorTests.h" + +NSData *GetDataForHex(NSString *hex) { + NSString *hexNoSpaces = [[[hex stringByReplacingOccurrencesOfString:@" " withString:@""] + stringByReplacingOccurrencesOfString:@"<" withString:@""] + stringByReplacingOccurrencesOfString:@">" withString:@""]; + + NSMutableData *data = [[NSMutableData alloc] init]; + unsigned char whole_byte = 0; + char byte_chars[3] = {'\0','\0','\0'}; + int i; + for (i=0; i < [hexNoSpaces length] / 2; i++) { + byte_chars[0] = (unsigned char)[hexNoSpaces characterAtIndex:i*2]; + byte_chars[1] = (unsigned char)[hexNoSpaces characterAtIndex:i*2+1]; + whole_byte = (unsigned char)strtol(byte_chars, NULL, 16); + [data appendBytes:&whole_byte length:1]; + } + return data; +} + +@implementation XCTestCase (RNCryptorVectorTests) + +- (void)verifyVector:(NSDictionary *)vector key:(NSString *)key equals:(NSData *)actual title:(NSString*)title { + XCTAssertEqualObjects(actual, GetDataForHex(vector[key]), @"Failed %@ test (v%@): %@\n", title, vector[@"version"], vector[@"title"]); +} + +- (void)_verifyKDF:(NSDictionary *)vector settings:(RNCryptorKeyDerivationSettings)keySettings name:(NSString *)name { + NSCParameterAssert(vector[@"title"]); + NSCParameterAssert(vector[@"version"]); + NSCParameterAssert(vector[@"password"]); + NSCParameterAssert(vector[@"salt_hex"]); + NSCParameterAssert(vector[@"key_hex"]); + + NSData *key = [RNCryptor keyForPassword:vector[@"password"] + salt:GetDataForHex(vector[@"salt_hex"]) + settings:keySettings]; + [self verifyVector:vector key:@"key_hex" equals:key title:name]; +} + +- (void)verify_v3_kdf:(NSDictionary *)vector { + RNCryptorKeyDerivationSettings settings = kRNCryptorAES256Settings.keySettings; + [self _verifyKDF:vector settings:settings name:@"kdf"]; +} + +- (void)verify_v2_kdf:(NSDictionary *)vector { + RNCryptorKeyDerivationSettings settings = kRNCryptorAES256Settings.keySettings; + settings.hasV2Password = YES; + [self _verifyKDF:vector settings:settings name:@"kdf"]; +} + +- (void)verify_v1_kdf:(NSDictionary *)vector { + RNCryptorKeyDerivationSettings settings = kRNCryptorAES256Settings.keySettings; + settings.hasV2Password = YES; + [self _verifyKDF:vector settings:settings name:@"kdf"]; +} + +- (void)_verifyPassword:(NSDictionary *)vector settings:(RNCryptorSettings)settings name:(NSString *)name { + NSCParameterAssert(vector[@"title"]); + NSCParameterAssert(vector[@"version"]); + NSCParameterAssert(vector[@"password"]); + NSCParameterAssert(vector[@"iv_hex"]); + NSCParameterAssert(vector[@"enc_salt_hex"]); + NSCParameterAssert(vector[@"hmac_salt_hex"]); + NSCParameterAssert(vector[@"plaintext_hex"]); + NSCParameterAssert(vector[@"ciphertext_hex"]); + + NSError *error; + + if ([vector[@"version"] intValue] == kRNCryptorFileVersion) { + NSData *ciphertext = [RNEncryptor encryptData:GetDataForHex(vector[@"plaintext_hex"]) + withSettings:settings + password:vector[@"password"] + IV:GetDataForHex(vector[@"iv_hex"]) + encryptionSalt:GetDataForHex(vector[@"enc_salt_hex"]) + HMACSalt:GetDataForHex(vector[@"hmac_salt_hex"]) + error:&error]; + [self verifyVector:vector key:@"ciphertext_hex" equals:ciphertext title:[name stringByAppendingString:@" encrypt"]]; + } + + NSData *plaintext = [RNDecryptor decryptData:GetDataForHex(vector[@"ciphertext_hex"]) + withPassword:vector[@"password"] + error:&error]; + [self verifyVector:vector key:@"plaintext_hex" equals:plaintext title:[name stringByAppendingString:@" encrypt"]]; +} + +- (void)verify_v3_password:(NSDictionary *)vector { + [self _verifyPassword:vector settings:kRNCryptorAES256Settings name:@"password"]; +} + +- (void)verify_v2_password:(NSDictionary *)vector { + [self _verifyPassword:vector settings:kRNCryptorAES256Settings name:@"password"]; +} + +- (void)verify_v1_password:(NSDictionary *)vector { + [self _verifyPassword:vector settings:kRNCryptorAES256Settings name:@"password"]; +} + +- (void)verify_v3_key:(NSDictionary *)vector { + NSCParameterAssert(vector[@"title"]); + NSCParameterAssert(vector[@"version"]); + NSCParameterAssert(vector[@"enc_key_hex"]); + NSCParameterAssert(vector[@"hmac_key_hex"]); + NSCParameterAssert(vector[@"iv_hex"]); + NSCParameterAssert(vector[@"plaintext_hex"]); + NSCParameterAssert(vector[@"ciphertext_hex"]); + + NSError *error; + + if ([vector[@"version"] intValue] == kRNCryptorFileVersion) { + NSData *ciphertext = [RNEncryptor encryptData:GetDataForHex(vector[@"plaintext_hex"]) + withSettings:kRNCryptorAES256Settings + encryptionKey:GetDataForHex(vector[@"enc_key_hex"]) + HMACKey:GetDataForHex(vector[@"hmac_key_hex"]) + IV:GetDataForHex(vector[@"iv_hex"]) + error:&error]; + [self verifyVector:vector key:@"ciphertext_hex" equals:ciphertext title:@"key encrypt"]; + } + + NSData *plaintext = [RNDecryptor decryptData:GetDataForHex(vector[@"ciphertext_hex"]) + withEncryptionKey:GetDataForHex(vector[@"enc_key_hex"]) + HMACKey:GetDataForHex(vector[@"hmac_key_hex"]) + error:&error]; + [self verifyVector:vector key:@"plaintext_hex" equals:plaintext title:@"key decrypt"]; +} +@end + + diff --git a/RNCryptorTests/test.enc b/RNCryptorTests/openssl.enc similarity index 100% rename from RNCryptorTests/test.enc rename to RNCryptorTests/openssl.enc diff --git a/RNCryptorVectors/RNCryptorVectors-Prefix.pch b/RNCryptorVectors/RNCryptorVectors-Prefix.pch deleted file mode 100644 index b56bdb90..00000000 --- a/RNCryptorVectors/RNCryptorVectors-Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'RNCryptorVectors' target in the 'RNCryptorVectors' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/RNCryptorVectors/main.m b/RNCryptorVectors/main.m deleted file mode 100644 index 8e037770..00000000 --- a/RNCryptorVectors/main.m +++ /dev/null @@ -1,85 +0,0 @@ -// -// main.m -// RNCryptorVectors -// -// Test vectors to assist porting -// -// - -#import -#import "RNEncryptor.h" -#import "RNDecryptor.h" -#import "RNCryptorEngine.h" - -void Encrypt(NSString *string, NSString *password, NSData *encryptionSalt, NSData *HMACSalt, NSData *IV) -{ - NSError *error = nil; - NSData *plaintext = [string dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encryptionKey = [RNCryptor keyForPassword:password - salt:encryptionSalt - settings:kRNCryptorAES256Settings.keySettings]; - - NSData *HMACKey =[RNCryptor keyForPassword:password - salt:HMACSalt - settings:kRNCryptorAES256Settings.keySettings]; - - - RNCryptorEngine *engine = [[RNCryptorEngine alloc] initWithOperation:kCCEncrypt - settings:kRNCryptorAES256Settings - key:encryptionKey - IV:IV - error:&error]; - - NSCAssert(engine && ! error, @"Failed engine:%@", error); - - NSMutableData *ciphertext = [NSMutableData new]; - [ciphertext appendData:[engine addData:plaintext error:&error]]; - [ciphertext appendData:[engine finishWithError:&error]]; - - NSCAssert(ciphertext && ! error, @"Failed encryption:%@", error); - - printf("string=%s\n", [string UTF8String]); - printf("plaintext=%s\n", [[plaintext description] UTF8String]); - printf("password=%s\n", [password UTF8String]); - printf("passwordData=%s\n", [[[password dataUsingEncoding:NSUTF8StringEncoding] description] UTF8String]); - printf("encryptionSalt=%s\n", [[encryptionSalt description] UTF8String]); - printf("HMACSalt=%s\n", [[HMACSalt description] UTF8String]); - printf("encryptionKey=%s\n", [[encryptionKey description] UTF8String]); - printf("HMACKey=%s\n", [[HMACKey description] UTF8String]); - printf("ciphertext=%s\n", [[ciphertext description] UTF8String]); - printf("---\n"); -} - -int main(int argc, const char * argv[]) -{ - @autoreleasepool { - NSString *string = @"Short Vector"; - NSString *password = @"password"; - NSData *encryptionSalt = [@"12345678" dataUsingEncoding:NSUTF8StringEncoding]; - NSData *HMACSalt = [@"87654321" dataUsingEncoding:NSUTF8StringEncoding]; - NSData *IV = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding]; - - Encrypt(string, password, encryptionSalt, HMACSalt, IV); - - string = @"This is a longer test vector intended to be longer than one block."; - - Encrypt(string, password, encryptionSalt, HMACSalt, IV); - - NSError *error; - NSData *encryptedData = [RNEncryptor encryptData:[string dataUsingEncoding:NSUTF8StringEncoding] - withSettings:kRNCryptorAES256Settings - password:password - error:&error]; - - [encryptedData writeToFile:@"/tmp/RNCryptor.enc" atomically:NO]; - - NSData *v1Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"RNCryptorV1.enc" ofType:nil]]; - - NSData *decryptedData = [RNDecryptor decryptData:v1Data withPassword:password error:&error]; - NSLog(@"decryptedData:%@", [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]); - NSLog(@"error:%@", error); - - } - return 0; -} - diff --git a/Spec b/Spec new file mode 160000 index 00000000..04378bc2 --- /dev/null +++ b/Spec @@ -0,0 +1 @@ +Subproject commit 04378bc27c604e97353badbead8c435698abe97a diff --git a/php/crypt-common.inc b/php/crypt-common.inc deleted file mode 100644 index 52f96e04..00000000 --- a/php/crypt-common.inc +++ /dev/null @@ -1,48 +0,0 @@ - \ No newline at end of file diff --git a/php/encrypt.php b/php/encrypt.php deleted file mode 100644 index 2153d56c..00000000 --- a/php/encrypt.php +++ /dev/null @@ -1,63 +0,0 @@ - \ No newline at end of file diff --git a/php/testphp/testphp.xcodeproj/project.pbxproj b/php/testphp/testphp.xcodeproj/project.pbxproj deleted file mode 100644 index b5cfc90b..00000000 --- a/php/testphp/testphp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,283 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - FBFBB5CC16B178DD002BA3EA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBFBB5CB16B178DD002BA3EA /* Foundation.framework */; }; - FBFBB5CF16B178DD002BA3EA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5CE16B178DD002BA3EA /* main.m */; }; - FBFBB5E216B178FD002BA3EA /* RNCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5DA16B178FD002BA3EA /* RNCryptor.m */; }; - FBFBB5E316B178FD002BA3EA /* RNCryptorEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5DD16B178FD002BA3EA /* RNCryptorEngine.m */; }; - FBFBB5E416B178FD002BA3EA /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5DF16B178FD002BA3EA /* RNDecryptor.m */; }; - FBFBB5E516B178FD002BA3EA /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5E116B178FD002BA3EA /* RNEncryptor.m */; }; - FBFBB5E916B17931002BA3EA /* Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFBB5E816B17931002BA3EA /* Base64.m */; }; - FBFBB5EB16B179D3002BA3EA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBFBB5EA16B179D3002BA3EA /* Security.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - FBFBB5C516B178DC002BA3EA /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - FBFBB5C716B178DD002BA3EA /* testphp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testphp; sourceTree = BUILT_PRODUCTS_DIR; }; - FBFBB5CB16B178DD002BA3EA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - FBFBB5CE16B178DD002BA3EA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - FBFBB5D116B178DD002BA3EA /* testphp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "testphp-Prefix.pch"; sourceTree = ""; }; - FBFBB5D916B178FD002BA3EA /* RNCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCryptor.h; path = ../../../RNCryptor/RNCryptor.h; sourceTree = ""; }; - FBFBB5DA16B178FD002BA3EA /* RNCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCryptor.m; path = ../../../RNCryptor/RNCryptor.m; sourceTree = ""; }; - FBFBB5DB16B178FD002BA3EA /* RNCryptor+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RNCryptor+Private.h"; path = "../../../RNCryptor/RNCryptor+Private.h"; sourceTree = ""; }; - FBFBB5DC16B178FD002BA3EA /* RNCryptorEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCryptorEngine.h; path = ../../../RNCryptor/RNCryptorEngine.h; sourceTree = ""; }; - FBFBB5DD16B178FD002BA3EA /* RNCryptorEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCryptorEngine.m; path = ../../../RNCryptor/RNCryptorEngine.m; sourceTree = ""; }; - FBFBB5DE16B178FD002BA3EA /* RNDecryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNDecryptor.h; path = ../../../RNCryptor/RNDecryptor.h; sourceTree = ""; }; - FBFBB5DF16B178FD002BA3EA /* RNDecryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNDecryptor.m; path = ../../../RNCryptor/RNDecryptor.m; sourceTree = ""; }; - FBFBB5E016B178FD002BA3EA /* RNEncryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNEncryptor.h; path = ../../../RNCryptor/RNEncryptor.h; sourceTree = ""; }; - FBFBB5E116B178FD002BA3EA /* RNEncryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNEncryptor.m; path = ../../../RNCryptor/RNEncryptor.m; sourceTree = ""; }; - FBFBB5E716B17931002BA3EA /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = ""; }; - FBFBB5E816B17931002BA3EA /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = ""; }; - FBFBB5EA16B179D3002BA3EA /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - FBFBB5C416B178DC002BA3EA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FBFBB5EB16B179D3002BA3EA /* Security.framework in Frameworks */, - FBFBB5CC16B178DD002BA3EA /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - FBFBB5BC16B178DC002BA3EA = { - isa = PBXGroup; - children = ( - FBFBB5EA16B179D3002BA3EA /* Security.framework */, - FBFBB5CD16B178DD002BA3EA /* testphp */, - FBFBB5CA16B178DD002BA3EA /* Frameworks */, - FBFBB5C816B178DD002BA3EA /* Products */, - ); - sourceTree = ""; - }; - FBFBB5C816B178DD002BA3EA /* Products */ = { - isa = PBXGroup; - children = ( - FBFBB5C716B178DD002BA3EA /* testphp */, - ); - name = Products; - sourceTree = ""; - }; - FBFBB5CA16B178DD002BA3EA /* Frameworks */ = { - isa = PBXGroup; - children = ( - FBFBB5CB16B178DD002BA3EA /* Foundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - FBFBB5CD16B178DD002BA3EA /* testphp */ = { - isa = PBXGroup; - children = ( - FBFBB5E616B1791C002BA3EA /* RNCryptor */, - FBFBB5CE16B178DD002BA3EA /* main.m */, - FBFBB5D016B178DD002BA3EA /* Supporting Files */, - ); - path = testphp; - sourceTree = ""; - }; - FBFBB5D016B178DD002BA3EA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - FBFBB5D116B178DD002BA3EA /* testphp-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - FBFBB5E616B1791C002BA3EA /* RNCryptor */ = { - isa = PBXGroup; - children = ( - FBFBB5D916B178FD002BA3EA /* RNCryptor.h */, - FBFBB5DA16B178FD002BA3EA /* RNCryptor.m */, - FBFBB5DB16B178FD002BA3EA /* RNCryptor+Private.h */, - FBFBB5DC16B178FD002BA3EA /* RNCryptorEngine.h */, - FBFBB5DD16B178FD002BA3EA /* RNCryptorEngine.m */, - FBFBB5DE16B178FD002BA3EA /* RNDecryptor.h */, - FBFBB5DF16B178FD002BA3EA /* RNDecryptor.m */, - FBFBB5E016B178FD002BA3EA /* RNEncryptor.h */, - FBFBB5E116B178FD002BA3EA /* RNEncryptor.m */, - FBFBB5E716B17931002BA3EA /* Base64.h */, - FBFBB5E816B17931002BA3EA /* Base64.m */, - ); - name = RNCryptor; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - FBFBB5C616B178DC002BA3EA /* testphp */ = { - isa = PBXNativeTarget; - buildConfigurationList = FBFBB5D616B178DD002BA3EA /* Build configuration list for PBXNativeTarget "testphp" */; - buildPhases = ( - FBFBB5C316B178DC002BA3EA /* Sources */, - FBFBB5C416B178DC002BA3EA /* Frameworks */, - FBFBB5C516B178DC002BA3EA /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = testphp; - productName = testphp; - productReference = FBFBB5C716B178DD002BA3EA /* testphp */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - FBFBB5BE16B178DC002BA3EA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - ORGANIZATIONNAME = "Rob Napier"; - }; - buildConfigurationList = FBFBB5C116B178DC002BA3EA /* Build configuration list for PBXProject "testphp" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = FBFBB5BC16B178DC002BA3EA; - productRefGroup = FBFBB5C816B178DD002BA3EA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - FBFBB5C616B178DC002BA3EA /* testphp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - FBFBB5C316B178DC002BA3EA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FBFBB5CF16B178DD002BA3EA /* main.m in Sources */, - FBFBB5E216B178FD002BA3EA /* RNCryptor.m in Sources */, - FBFBB5E316B178FD002BA3EA /* RNCryptorEngine.m in Sources */, - FBFBB5E416B178FD002BA3EA /* RNDecryptor.m in Sources */, - FBFBB5E516B178FD002BA3EA /* RNEncryptor.m in Sources */, - FBFBB5E916B17931002BA3EA /* Base64.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - FBFBB5D416B178DD002BA3EA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - FBFBB5D516B178DD002BA3EA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - SDKROOT = macosx; - }; - name = Release; - }; - FBFBB5D716B178DD002BA3EA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "testphp/testphp-Prefix.pch"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - FBFBB5D816B178DD002BA3EA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "testphp/testphp-Prefix.pch"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - FBFBB5C116B178DC002BA3EA /* Build configuration list for PBXProject "testphp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FBFBB5D416B178DD002BA3EA /* Debug */, - FBFBB5D516B178DD002BA3EA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - FBFBB5D616B178DD002BA3EA /* Build configuration list for PBXNativeTarget "testphp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FBFBB5D716B178DD002BA3EA /* Debug */, - FBFBB5D816B178DD002BA3EA /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = FBFBB5BE16B178DC002BA3EA /* Project object */; -} diff --git a/php/testphp/testphp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/php/testphp/testphp.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index e69ceefa..00000000 --- a/php/testphp/testphp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/php/testphp/testphp/Base64.h b/php/testphp/testphp/Base64.h deleted file mode 100644 index 336bbff7..00000000 --- a/php/testphp/testphp/Base64.h +++ /dev/null @@ -1,202 +0,0 @@ -// -// Base64.m -// -// Version 1.1 -// -// Created by Nick Lockwood on 12/01/2012. -// Copyright (C) 2012 Charcoal Design -// -// Distributed under the permissive zlib License -// Get the latest version from here: -// -// https://github.com/nicklockwood/Base64 -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#import "Base64.h" - - -#import -#if !__has_feature(objc_arc) -#error This library requires automatic reference counting -#endif - - -@implementation NSData (Base64) - -+ (NSData *)dataWithBase64EncodedString:(NSString *)string -{ - const char lookup[] = - { - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 62, 99, 99, 99, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 99, 99, 99, 99, 99, 99, - 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99, 99, 99, 99, 99, - 99, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 99, 99, 99, 99, 99 - }; - - NSData *inputData = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; - long long inputLength = [inputData length]; - const unsigned char *inputBytes = [inputData bytes]; - - long long maxOutputLength = (inputLength / 4 + 1) * 3; - NSMutableData *outputData = [NSMutableData dataWithLength:maxOutputLength]; - unsigned char *outputBytes = (unsigned char *)[outputData mutableBytes]; - - int accumulator = 0; - long long outputLength = 0; - unsigned char accumulated[] = {0, 0, 0, 0}; - for (long long i = 0; i < inputLength; i++) - { - unsigned char decoded = lookup[inputBytes[i] & 0x7F]; - if (decoded != 99) - { - accumulated[accumulator] = decoded; - if (accumulator == 3) - { - outputBytes[outputLength++] = (accumulated[0] << 2) | (accumulated[1] >> 4); - outputBytes[outputLength++] = (accumulated[1] << 4) | (accumulated[2] >> 2); - outputBytes[outputLength++] = (accumulated[2] << 6) | accumulated[3]; - } - accumulator = (accumulator + 1) % 4; - } - } - - //handle left-over data - if (accumulator > 0) outputBytes[outputLength] = (accumulated[0] << 2) | (accumulated[1] >> 4); - if (accumulator > 1) outputBytes[++outputLength] = (accumulated[1] << 4) | (accumulated[2] >> 2); - if (accumulator > 2) outputLength++; - - //truncate data to match actual output length - outputData.length = outputLength; - return outputLength? outputData: nil; -} - -- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth -{ - //ensure wrapWidth is a multiple of 4 - wrapWidth = (wrapWidth / 4) * 4; - - const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - long long inputLength = [self length]; - const unsigned char *inputBytes = [self bytes]; - - long long maxOutputLength = (inputLength / 3 + 1) * 4; - maxOutputLength += wrapWidth? (maxOutputLength / wrapWidth) * 2: 0; - unsigned char *outputBytes = (unsigned char *)malloc(maxOutputLength); - - long long i; - long long outputLength = 0; - for (i = 0; i < inputLength - 2; i += 3) - { - outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; - outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)]; - outputBytes[outputLength++] = lookup[((inputBytes[i + 1] & 0x0F) << 2) | ((inputBytes[i + 2] & 0xC0) >> 6)]; - outputBytes[outputLength++] = lookup[inputBytes[i + 2] & 0x3F]; - - //add line break - if (wrapWidth && (outputLength + 2) % (wrapWidth + 2) == 0) - { - outputBytes[outputLength++] = '\r'; - outputBytes[outputLength++] = '\n'; - } - } - - //handle left-over data - if (i == inputLength - 2) - { - // = terminator - outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; - outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)]; - outputBytes[outputLength++] = lookup[(inputBytes[i + 1] & 0x0F) << 2]; - outputBytes[outputLength++] = '='; - } - else if (i == inputLength - 1) - { - // == terminator - outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; - outputBytes[outputLength++] = lookup[(inputBytes[i] & 0x03) << 4]; - outputBytes[outputLength++] = '='; - outputBytes[outputLength++] = '='; - } - - if (outputLength >= 4) - { - //truncate data to match actual output length - outputBytes = realloc(outputBytes, outputLength); - return [[NSString alloc] initWithBytesNoCopy:outputBytes - length:outputLength - encoding:NSASCIIStringEncoding - freeWhenDone:YES]; - } - else if (outputBytes) - { - free(outputBytes); - } - return nil; -} - -- (NSString *)base64EncodedString -{ - return [self base64EncodedStringWithWrapWidth:0]; -} - -@end - - -@implementation NSString (Base64) - -+ (NSString *)stringWithBase64EncodedString:(NSString *)string -{ - NSData *data = [NSData dataWithBase64EncodedString:string]; - if (data) - { - return [[self alloc] initWithData:data encoding:NSUTF8StringEncoding]; - } - return nil; -} - -- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth -{ - NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; - return [data base64EncodedStringWithWrapWidth:wrapWidth]; -} - -- (NSString *)base64EncodedString -{ - NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; - return [data base64EncodedString]; -} - -- (NSString *)base64DecodedString -{ - return [NSString stringWithBase64EncodedString:self]; -} - -- (NSData *)base64DecodedData -{ - return [NSData dataWithBase64EncodedString:self]; -} - -@end \ No newline at end of file diff --git a/php/testphp/testphp/Base64.m b/php/testphp/testphp/Base64.m deleted file mode 100644 index cbaeb6e5..00000000 --- a/php/testphp/testphp/Base64.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// Base64.h -// -// Version 1.1 -// -// Created by Nick Lockwood on 12/01/2012. -// Copyright (C) 2012 Charcoal Design -// -// Distributed under the permissive zlib License -// Get the latest version from here: -// -// https://github.com/nicklockwood/Base64 -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#import - - -@interface NSData (Base64) - -+ (NSData *)dataWithBase64EncodedString:(NSString *)string; -- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth; -- (NSString *)base64EncodedString; - -@end - - -@interface NSString (Base64) - -+ (NSString *)stringWithBase64EncodedString:(NSString *)string; -- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth; -- (NSString *)base64EncodedString; -- (NSString *)base64DecodedString; -- (NSData *)base64DecodedData; - -@end \ No newline at end of file diff --git a/php/testphp/testphp/main.m b/php/testphp/testphp/main.m deleted file mode 100644 index 5cc52953..00000000 --- a/php/testphp/testphp/main.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// main.m -// testphp -// -// Created by Rob Napier on 1/24/13. -// Copyright (c) 2013 Rob Napier. All rights reserved. -// - -#import -#import "RNDecryptor.h" -#import "Base64.h" - -int main(int argc, const char * argv[]) -{ - - @autoreleasepool { - NSError *decryptionError = nil; - // Output of encrypt.php - NSData *fromPHPData = [@"AgF12bfxXb0lpR5tJAWTNb9jRUyyhTS5A8GBu5M1qhwA7CV0NMqHYTsyEsDjSccQiohU+FV9wk+VzGDrRmEpoK6PnVKTmsmJpnlqftxOv9BXlkmHIiEBCXzTprhzv4lWQ2MiEKkx+zda9B4WEoBuMTPxdLwnAxek9baTgv9mDH64oPmhZZWtlG3s9gSEaA1Cu2uYScDOin3+T1sEOdVAbnJG" base64DecodedData]; - - NSData *fromPHPDecryptedData = [RNDecryptor decryptData:fromPHPData withPassword:@"myPassword" error:&decryptionError]; - - NSLog(@"decryptionError %@", decryptionError); - NSLog(@"Result = %@", fromPHPDecryptedData); - NSLog(@"Result = %@", [[NSString alloc] initWithData:fromPHPDecryptedData encoding:NSUTF8StringEncoding]); - - } - return 0; -} - diff --git a/php/testphp/testphp/testphp-Prefix.pch b/php/testphp/testphp/testphp-Prefix.pch deleted file mode 100644 index d9fee584..00000000 --- a/php/testphp/testphp/testphp-Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'testphp' target in the 'testphp' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/python/.gitignore b/python/.gitignore deleted file mode 100644 index 0d20b648..00000000 --- a/python/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/python/RNCryptor.py b/python/RNCryptor.py deleted file mode 100755 index bb15dfe9..00000000 --- a/python/RNCryptor.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python - -import Crypto.Hash.SHA -import Crypto.Hash.SHA256 -import Crypto.Random -import Crypto.Protocol.KDF -import Crypto.Cipher.AES -import Crypto.Hash.HMAC -import StringIO - -class RNCryptor: - """Cryptor for RNCryptor""" - - salt_size = 8 - key_length = 32 - iterations = 10000 - HMAC_hash_algo = Crypto.Hash.SHA256 - block_size = Crypto.Cipher.AES.block_size - mode = Crypto.Cipher.AES.MODE_CBC - - def encrypt(self, message, password): - random = Crypto.Random.new() - - encryption_salt = random.read(self.salt_size) - encryption_key = Crypto.Protocol.KDF.PBKDF2(password, encryption_salt, self.key_length, self.iterations) - - hmac_salt = random.read(self.salt_size) - hmac_key = Crypto.Protocol.KDF.PBKDF2(password, hmac_salt, self.key_length, self.iterations) - - iv = random.read(self.block_size) - cipher = Crypto.Cipher.AES.new(encryption_key, self.mode, iv) - - ciphertext = cipher.encrypt(self.pad(message)) - - output = StringIO.StringIO() - output.write(chr(2)) # Version 2 - output.write(chr(1)) # Password - output.write(encryption_salt) - output.write(hmac_salt) - output.write(iv) - output.write(ciphertext) - - hmac = Crypto.Hash.HMAC.new(hmac_key, output.getvalue(), self.HMAC_hash_algo) - - output.write(hmac.digest()) - - return output.getvalue() - - def pad(self, data): - block_size = self.block_size - return data + (block_size - len(data) % block_size) * chr(block_size - len(data) % block_size) - -def main(): - plaintext = b"Attack at dawn" - password = b"mypassword" - - message = RNCryptor().encrypt(plaintext, password) - print ''.join('%02x' % ord(byte) for byte in message) - -if __name__ == '__main__': - main() diff --git a/rncrypt/main.m b/rncrypt/main.m index 472b04e7..1f03731a 100644 --- a/rncrypt/main.m +++ b/rncrypt/main.m @@ -42,7 +42,7 @@ void OutputData(NSData *data) printf("%s\n", [string UTF8String]); } else { - printf("%s\n", [[data description] UTF8String]); + printf("%s\n", [[data base64EncodedStringWithOptions:0] UTF8String]); } } @@ -86,7 +86,8 @@ int main(int argc, char * const argv[]) NSError *error; NSData *data; if (decrypt_flag) { - data = [RNDecryptor decryptData:GetDataForHex(message) + data = [RNDecryptor decryptData:[[NSData alloc] initWithBase64EncodedString:message + options:NSDataBase64DecodingIgnoreUnknownCharacters] withPassword:password error:&error]; } diff --git a/ruby/LICENSE.txt b/ruby/LICENSE.txt deleted file mode 100644 index 7df6b18a..00000000 --- a/ruby/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -MIT License - -Copyright (C) 2013 Erik Wrenholt - -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/ruby/README.md b/ruby/README.md deleted file mode 100644 index ff7727b2..00000000 --- a/ruby/README.md +++ /dev/null @@ -1,28 +0,0 @@ -Ruby RNCryptor --------------- - -This is a Ruby port of Rob Napier's Cocoa [RNCryptor](https://github.com/rnapier/RNCryptor/) library. Like RNCryptor, Ruby RNCryptor intends to be an easy-to-use class that correctly handles random initialization vectors, password stretching with PBKDF2, and HMAC verification. - -This port is based on his [Data Format](https://github.com/rnapier/RNCryptor/wiki/Data-Format) wiki page. It currently only implements version 2. - -Usage Example: -------------- - - require './lib/ruby_rncryptor' - require "base64" - - password = "n3v3r gue55!!" - encrypted = RubyRNCryptor.encrypt("This is a tiny bit of text to encrypt", password) - - puts Base64.encode64(encrypted) - puts "Decrypting..." - - decrypted = RubyRNCryptor.decrypt(encrypted, password) - - puts decrypted - -Credits -------- - -- Ruby port by Erik Wrenholt 2013. -- Original RNCrypto library and format are by Rob Napier. diff --git a/ruby/Rakefile.rb b/ruby/Rakefile.rb deleted file mode 100644 index 7d35cca6..00000000 --- a/ruby/Rakefile.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'rubygems' -require 'rspec/core/rake_task' -require 'rake' - -task :default => :spec -RSpec::Core::RakeTask.new(:spec) \ No newline at end of file diff --git a/ruby/example.rb b/ruby/example.rb deleted file mode 100644 index 4fa847b7..00000000 --- a/ruby/example.rb +++ /dev/null @@ -1,14 +0,0 @@ -require './lib/ruby_rncryptor' -require "base64" - -password = "n3v3r gue55!!" - -encrypted = RubyRNCryptor.encrypt("This is a tiny bit of text to encrypt", password) -puts Base64.encode64(encrypted) - -puts -puts "Decrypting..." - -decrypted = RubyRNCryptor.decrypt(encrypted, password) - -puts decrypted \ No newline at end of file diff --git a/ruby/lib/ruby_rncryptor.rb b/ruby/lib/ruby_rncryptor.rb deleted file mode 100644 index e6930196..00000000 --- a/ruby/lib/ruby_rncryptor.rb +++ /dev/null @@ -1,64 +0,0 @@ -# RubyRNCryptor by Erik Wrenholt. -# Based on data format described by Rob Napier -# https://github.com/rnapier/RNCryptor/wiki/Data-Format -# MIT License - -require 'openssl' - -class RubyRNCryptor - include OpenSSL - - def self.decrypt(data, password) - - version = data[0,1] - raise "RubyRNCryptor only supports version 2" if version != "\x02" - options = data[1,1] - encryption_salt = data[2,8] - hmac_salt = data[10,8] - iv = data[18,16] - cipher_text = data[34,data.length-66] - hmac = data[data.length-32,32] - - key = PKCS5.pbkdf2_hmac_sha1(password, encryption_salt, 10000, 32) - hmac_key = PKCS5.pbkdf2_hmac_sha1(password, hmac_salt, 10000, 32) - - # Verify password is correct. - msg = version + options + encryption_salt + hmac_salt + iv + cipher_text - verified = [HMAC.hexdigest('sha256', hmac_key, msg)].pack('H*') == hmac - raise "HMAC could not be verified. Password may be incorrect, or the data has been corrupted." unless verified - - # HMAC was verified, now decrypt it. - cipher = Cipher::Cipher.new('aes-256-cbc') - cipher.decrypt - cipher.iv = iv - cipher.key = key - - return cipher.update(cipher_text) + cipher.final - end - - def self.encrypt(data, password) - - version = 0x02.chr.to_s # Currently version 2 - options = 0x01.chr.to_s # Uses password - encryption_salt = Random.random_bytes(8) - hmac_salt = Random.random_bytes(8) - iv = Random.random_bytes(16) - - cipher_text = data[34,data.length-66] - - key = PKCS5.pbkdf2_hmac_sha1(password, encryption_salt, 10000, 32) - hmac_key = PKCS5.pbkdf2_hmac_sha1(password, hmac_salt, 10000, 32) - - cipher = Cipher::Cipher.new('aes-256-cbc') - cipher.encrypt - cipher.iv = iv - cipher.key = key - cipher_text = cipher.update(data) + cipher.final - - msg = version + options + encryption_salt + hmac_salt + iv + cipher_text - hmac = [HMAC.hexdigest('sha256', hmac_key, msg)].pack('H*') - - return msg + hmac - end - -end diff --git a/ruby/spec/ruby_rncryptor_spec.rb b/ruby/spec/ruby_rncryptor_spec.rb deleted file mode 100644 index 12d1436c..00000000 --- a/ruby/spec/ruby_rncryptor_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require File.join(File.dirname(__FILE__), '../lib/ruby_rncryptor.rb') - -describe RubyRNCryptor do - - before :each do - @plain_text = "Hello, World! Let's use a few blocks with a longer sentence." - @encrypted_data = ["02013F194AA9969CF70C8ACB76824DE4CB6CDCF78B7449A87C679FB8EDB6A0109C513481DE877F3A855A184C4947F2B3E8FEF7E916E4739F9F889A717FCAF277402866341008A09FD3EBAC7FA26C969DD7EE72CFB695547C971A75D8BF1CC5980E0C727BD9F97F6B7489F687813BEB94DEB61031260C246B9B0A78C2A52017AA8C92"].pack('H*') - @password = "P@ssw0rd!" - end - - it "Decrypt with password" do - decrypted = RubyRNCryptor.decrypt(@encrypted_data, @password) - decrypted.should == @plain_text - end - - it "Encrypt with password should decrypt" do - encrypted = RubyRNCryptor.encrypt(@plain_text, @password) - RubyRNCryptor.decrypt(encrypted, @password).should == @plain_text - end - - it "Encrypt lots of data with password and it should decrypt" do - bigger_data = OpenSSL::Random.random_bytes(4043) - encrypted = RubyRNCryptor.encrypt(bigger_data, @password) - RubyRNCryptor.decrypt(encrypted, @password).should == bigger_data - end - - it "Decrypt with wrong password should result in an error" do - encrypted = RubyRNCryptor.encrypt(@plain_text, @password) - expect { RubyRNCryptor.decrypt(encrypted, "WRONG") }.to raise_error - end - -end diff --git a/test.enc b/test.enc deleted file mode 100644 index 57a7c03d..00000000 --- a/test.enc +++ /dev/null @@ -1 +0,0 @@ -Salted__[U$@經r*›efo \ No newline at end of file