Giter Site home page Giter Site logo

henrinormak / heimdall Goto Github PK

View Code? Open in Web Editor NEW
401.0 16.0 68.0 470 KB

Heimdall is a wrapper around the Security framework for simple encryption/decryption operations.

License: MIT License

Swift 95.84% Ruby 1.93% Objective-C 2.23%
swift ios security rsa aes encrypted-messages

heimdall's Introduction

Heimdall Helmet

Build Status CocoaPods compatible Carthage compatible

Heimdall

In Norse mythology, Heimdall is the gatekeeper of Bifröst, the rainbow road connecting Midgard, realm of the humans, to Asgard, the realm of gods.

In iOS, Heimdall serves as a gatekeeper between Security framework and the UI, offering a nice wrapper around the C APIs for encrypting, decrypting, signing and verifying messages.

Furthermore, Heimdall also helps maintain the public-private RSA key-pair in Keychain, allowing both creating as well as deleting the key pairs.

Requirements

Heimdall requires Swift 3 and works with only Xcode 8 and above

Installation

CocoaPods

Heimdall is available as a CocoaPod, simply add the following line to your Podfile

pod 'Heimdall', '~> 1.1.0'

Also, make sure your podfile includes the following line, which is necessary to support Swift frameworks

use_frameworks!

Carthage

Simply include the following line in your Cartfile

github "henrinormak/Heimdall"

Note that Heimdall produces two frameworks in the Carthage build directory - Heimdall.framework and CommonCrypto.framework, you only need to include/embed Heimdall.framework into your project.

Subproject

As Heimdall makes use of CommonCrypto and has it wrapped in a pseudo-module, the easiest way to use Heimdall is to include the entire project as a subproject in your workspace.

To do this, include Heimdall.xcodeproj (found in Heimdall folder) into your Xcode workspace. Then specify the Heimdall target as a Target Dependency for your main application target.

Target Dependency selection in Xcode

Finally, make sure Heimdall is listed under the Embedded Binaries section in Xcode

Embedded Binaries under application target settings

Directly

Although not recommended, you can also add Heimdall directly, by including Heimdall.swift in your project.

Usage

Using Heimdall is simple, for public-private key-pair, you just have to create an instance, which can be used for encryption/decryption, signing/verifying.

With this method you can locally encrypt data to be stored on disk or in a database, without putting everything in the Keychain.

if let heimdall = Heimdall(tagPrefix: "com.example") {
    let testString = "This is a test string"

    // Encryption/Decryption
    if let encryptedString = heimdall.encrypt(testString) {
        println(encryptedString) // "cQzaQCQLhAWqkDyPoHnPrpsVh..."

        if let decryptedString = heimdall.decrypt(encryptedString) {
            println(decryptedString) // "This is a test string"
        }
    }

    // Signatures/Verification
    if let signature = heimdall.sign(testString) {
        println(signature) // "fMVOFj6SQ7h+cZTEXZxkpgaDsMrki..."
        var verified = heimdall.verify(testString, signatureBase64: signature)
        println(verified) // True

        // If someone meddles with the message and the signature becomes invalid
        verified = heimdall.verify(testString + "injected false message",
                                    signatureBase64: signature)
        println(verified) // False
    }
}

Note on encryption/decryption

As RSA imposes a limit on the length of message that can be enrcypted, Heimdall uses a mix of AES and RSA to encrypt messages of arbitrary length. This is done in the following manner:

  1. A random AES key of suitable length is generated, the length is based on the size of the RSA key pair (either 128, 192 or 256 bits) *
  2. The message is encrypted with this AES key
  3. The key is encrypted with the public part of the RSA key pair (and padded to the correct block size) *
  4. The payload is built, containing the encrypted key, followed by the encrypted message. During decryption, the first block is always assumed to be the RSA encrypted AES key, this is why Heimdall can only decrypt messages encrypted by other Heimdall instances (or code that is compatible with Heimdall's logic) *

Complex use case

A more complex use case involves exchanging encrypted messages between multiple Heimdall instances, which can be situated on multiple different hosts.

First step is to share your public key with another party:

let localHeimdall = Heimdall(tagPrefix: "com.example")
if let heimdall = localHeimdall, publicKeyData = heimdall.publicKeyDataX509() {

    var publicKeyString = publicKeyData.base64EncodedString()

    // If you want to make this string URL safe,
    // you have to remember to do the reverse on the other side later
    publicKeyString = publicKeyString.replacingOccurrences(of: "/", with: "_")
    publicKeyString = publicKeyString.replacingOccurrences(of: "+", with: "-")

    println(publicKeyString) // Something along the lines of "MIGfMA0GCSqGSIb3DQEBAQUAA..."

    // Data transmission of public key to the other party
}

Second step, acting as the recipient (the one that wants to send the encrypted message), you receive the public key extracted and create a matching Heimdall instance:

// On other party, assuming keyData contains the received public key data
if let partnerHeimdall = Heimdall(publicTag: "com.example.partner", publicKeyData: keyData) {
    // Transmit some message to the partner
    let message = "This is a secret message to my partner"
    let encryptedMessage = partnerHeimdall.encrypt(message)

    // Transmit the encryptedMessage back to the origin of the public key
}

Finally, having received the encrypted message, the party that sent out the public key can decrypt it using the original Heimdall instance they had:

// Initial host receives encryptedMessage
if let heimdall = localHeimdall {
    if let decryptedMessage = heimdall.decrypt(encryptedMessage) {
        println(decryptedMessage) // "This is a secret message to my partner"
    }
}

The workflow should be mirrored on all hosts, extracting their public keys and sharing those to all other parties. The public keys can be used to construct special Heimdall instances that are only able to encrypt messages and verify signatures.

Contributing and Current Work

Contributions to the codebase are very welcome, for ideas on what is needed, have a look through the open issues. In addition, any suggestions regarding the following topics are welcome:

  • Security, interacting with the Keychain, making sure the results are kept securely etc.
  • Tests, adding tests would also likely increase security
  • Additional configurability, perhaps allowing non-permanent keys
  • Error handling, currently most of the API simply returns nils whenever an error occurs, this should be changed and proper error reporting should be implemented
  • Reducing the number of optionals in the public API of the Heimdall instances.

Contact

If you have any questions, don't hesitate to contact me. In case of bugs, create an issue here on GitHub

Henri Normak

License

The MIT License (MIT)

Copyright (c) 2015 Henri Normak

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.

heimdall's People

Contributors

arcz avatar elliottpolk avatar henrinormak avatar jorystiefel avatar nathankot avatar paugp avatar rajeevpra avatar sealz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

heimdall's Issues

Not swift 3 ready?

I used pod to add your module to an app I am testing, but after I got it installed using pod, I received several (110) errors in my app.
All seems to be because of swift 3 which I am using in my app.

Heimdall Group
Swift Compiler Error Group
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:59:73: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:64:74: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:151:50: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:177:100: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:222:68: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:223:17: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:269:111: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:341:100: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:365:43: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:412:101: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:429:42: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:462:49: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:490:45: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:533:45: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:543:45: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:650:47: Expected 'let' in conditional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:777:40: 'inout' before a parameter name is not allowed, place it before the parameter type instead
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:815:44: Expected ',' joining parts of a multi-clause condition
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:151:40: Missing argument label 'key:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:177:30: 'dataUsingEncoding(:allowLossyConversion:)' has been renamed to 'data(usingEncoding:allowLossyConversion:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.String:21:17: 'dataUsingEncoding(
:allowLossyConversion:)' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:177:48: 'NSUTF8StringEncoding' has been renamed to 'String.Encoding.utf8'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.NSUTF8StringEncoding:2:12: 'NSUTF8StringEncoding' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:177:117: Argument labels '(:)' do not match any available overloads
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:177:117: Overloads for 'encrypt' exist with these partially matching parameter lists: (string: String, urlEncode: Bool), (data: NSData)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:222:58: Missing argument label 'count:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:269:68: 'NSDataBase64DecodingOptions' has been renamed to 'NSData.Base64DecodingOptions'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:269:68: 'NSDataBase64DecodingOptions' was obsoleted in Swift 3
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:341:30: 'dataUsingEncoding(
:allowLossyConversion:)' has been renamed to 'data(usingEncoding:allowLossyConversion:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.String:21:17: 'dataUsingEncoding(:allowLossyConversion:)' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:341:48: 'NSUTF8StringEncoding' has been renamed to 'String.Encoding.utf8'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.NSUTF8StringEncoding:2:12: 'NSUTF8StringEncoding' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:341:121: Argument labels '(
:)' do not match any available overloads
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:341:121: Overloads for 'sign' exist with these partially matching parameter lists: (string: String, urlEncode: Bool), (data: NSData)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:412:31: 'dataUsingEncoding(:allowLossyConversion:)' has been renamed to 'data(usingEncoding:allowLossyConversion:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.String:21:17: 'dataUsingEncoding(
:allowLossyConversion:)' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:412:49: 'NSUTF8StringEncoding' has been renamed to 'String.Encoding.utf8'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Foundation.NSUTF8StringEncoding:2:12: 'NSUTF8StringEncoding' has been explicitly marked unavailable here
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:412:158: 'NSDataBase64DecodingOptions' has been renamed to 'NSData.Base64DecodingOptions'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:412:158: 'NSDataBase64DecodingOptions' was obsoleted in Swift 3
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:462:74: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:533:81: Binary operator '&' cannot be applied to two 'Heimdall.ScopeOptions' operands
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:533:81: Overloads for '&' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:543:81: Binary operator '&' cannot be applied to two 'Heimdall.ScopeOptions' operands
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:543:81: Overloads for '&' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:57:54: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:60:35: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:140:40: Missing argument label 'key:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:162:30: Missing argument label 'key:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:207:45: Missing argument label 'algorithm:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:265:22: Value of type 'String' has no member 'stringByReplacingOccurrencesOfString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:266:22: Value of type 'String' has no member 'stringByReplacingOccurrencesOfString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:288:45: Missing argument label 'algorithm:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:368:57: Cannot invoke initializer for type 'UnsafeMutablePointer<>' with an argument list of type '(UnsafeMutableRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:368:57: Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:368:57: Overloads for 'UnsafeMutablePointer<
>' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafeMutablePointer), (UnsafeMutablePointer?)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:374:28: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:374:28: Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:374:28: Overloads for 'UnsafePointer' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafePointer), (UnsafePointer?), (UnsafeMutablePointer), (UnsafeMutablePointer?)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:408:22: Value of type 'String' has no member 'stringByReplacingOccurrencesOfString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:409:22: Value of type 'String' has no member 'stringByReplacingOccurrencesOfString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:430:57: Cannot invoke initializer for type 'UnsafeMutablePointer<>' with an argument list of type '(UnsafeMutableRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:430:57: Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:430:57: Overloads for 'UnsafeMutablePointer<
>' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafeMutablePointer), (UnsafeMutablePointer?)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:432:30: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:432:30: Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:432:30: Overloads for 'UnsafePointer' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafePointer), (UnsafePointer?), (UnsafeMutablePointer), (UnsafeMutablePointer?)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:434:33: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:434:33: Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:434:33: Overloads for 'UnsafePointer' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafePointer), (UnsafePointer?), (UnsafeMutablePointer), (UnsafeMutablePointer?)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:459:31: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:460:54: Unary operator '' cannot be applied to an operand of type 'Heimdall.ScopeOptions'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:460:54: Overloads for '
' exist with these partially matching parameter lists: (UInt8), (Int8), (UInt16), (Int16), (UInt32), (Int32), (UInt64), (Int64), (UInt), (Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:463:58: Unary operator '' cannot be applied to an operand of type 'Heimdall.ScopeOptions'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:463:58: Overloads for '
' exist with these partially matching parameter lists: (UInt8), (Int8), (UInt16), (Int16), (UInt32), (Int32), (UInt64), (Int64), (UInt), (Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:486:23: Binary operator '&' cannot be applied to two 'Heimdall.ScopeOptions' operands
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:486:23: Overloads for '&' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:509:34: 'OptionSetType' has been renamed to 'OptionSet'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:509:34: 'OptionSetType' has been explicitly marked unavailable here (Swift.OptionSetType)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:530:45: 'SecKeyRef' has been renamed to 'SecKey'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:531:41: Binary operator '&' cannot be applied to two 'Heimdall.ScopeOptions' operands
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:531:41: Overloads for '&' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:541:41: Binary operator '&' cannot be applied to two 'Heimdall.ScopeOptions' operands
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:541:41: Overloads for '&' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:542:43: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:544:43: Missing argument label 'tag:' in call
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:554:50: 'SecKeyRef' has been renamed to 'SecKey'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:559:48: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:563:42: Cannot convert value of type 'Dictionary<String, AnyObject>' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:582:48: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:588:36: Cannot convert value of type 'Dictionary<String, AnyObject>' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:601:48: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:604:30: Cannot convert value of type 'Dictionary<String, AnyObject>' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:610:48: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:613:30: Cannot convert value of type 'Dictionary<String, AnyObject>' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:616:76: 'SecKeyRef' has been renamed to 'SecKey'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:619:63: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:620:73: 'CFStringRef' has been renamed to 'CFString'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:621:59: 'CFDataRef' has been renamed to 'CFData'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:622:69: 'CFBooleanRef' has been renamed to 'CFBoolean'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:625:33: Cannot convert value of type 'Dictionary<String, AnyObject>' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:635:108: 'SecKeyRef' has been renamed to 'SecKey'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:636:33: Heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:638:32: Heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:641:30: Heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:648:35: Cannot convert value of type '[String : Any]' to expected argument type 'CFDictionary'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:661:44: Argument 'repeatedValue' must precede argument 'count'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:688:25: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:692:27: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:694:26: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:696:33: Cannot invoke initializer for type 'UnsafeMutablePointer' with an argument list of type '(UnsafeMutableRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:713:29: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:717:27: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:719:26: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:721:33: Cannot invoke initializer for type 'UnsafeMutablePointer' with an argument list of type '(UnsafeMutableRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:742:59: 'ScopeOptions' is inaccessible due to 'private' protection level
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:746:62: 'ScopeOptions' is inaccessible due to 'private' protection level
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:750:84: 'ScopeOptions' is inaccessible due to 'private' protection level
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:770:26: Incorrect argument label in call (have ':atIndex:', expected ':at:')
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:784:57: Ambiguous use of operator '-'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:811:86: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:812:87: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:833:14: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:834:26: Incorrect argument label in call (have 'keepCapacity:', expected 'keepingCapacity:')
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:839:14: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:840:26: Incorrect argument label in call (have 'keepCapacity:', expected 'keepingCapacity:')
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:846:14: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:849:25: 'NSMutableData' is not implicitly convertible to 'Data'; did you mean to use 'as' to explicitly convert?
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:854:23: Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:909:17: 'appendContentsOf' has been renamed to 'append(contentsOf:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:910:16: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:911:16: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:912:26: Incorrect argument label in call (have 'keepCapacity:', expected 'keepingCapacity:')
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:915:17: 'appendContentsOf' has been renamed to 'append(contentsOf:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:917:16: 'appendBytes(:length:)' has been renamed to 'append(:length:)'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:920:27: 'NSData' is not implicitly convertible to 'Data'; did you mean to use 'as' to explicitly convert?
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:926:57: Argument 'repeatedValue' must precede argument 'count'
/Users/ssaguiar/work/IosWorkspace/ipTv3/Pods/Heimdall/Heimdall/Heimdall.swift:969:21: 'subdataWithRange' has been renamed to 'subdata(with:)'

Import Private Keys

Is there the possibiliy to import a keypair received from a server?
I have all keys in modulus/exponent (String) format.

How to not use OAEP?

I'm attempting to integrate a fork of Heimdall with some other platforms that don't have the ability to do OAEP (long story short, the Android keystore didn't support it until a recent SDK version). I see a comment in the code that calculates the AES key size that says "Assumes SHA1-OAEP is used", but it's unclear to me what logic or values are based on that assumption. Say I were to switch to using SecPadding.PKCS1, would something in this logic need to be updated? Thanks in advance for any info you can provide.

Android Compatibility

Hello there,
I'm working on exchanging encrypted data between my iOS and Android apps. Intra-platform communication is working perfectly for both iOS and Android. Now the exchange between iOS and Android is running into a decryption problem on the iOS side using Heimdall. I followed the Heimdall logic while writing the Android app as you can see below, but it seems some encoding or padding discrepancies caused the problem. Could any of the mentioned have caused the problem?

String stringToShare = "Test String to Share";
        String userPublicKi = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1dOgSE2sPXDaHurcDygJsZojtA4HX3kV+2Msc0HpImSLpza5pJ5nz957Zp2XRprxImatAEx6kkKjII8PBKXyu74jEHqFP9ObzkDc/ZzhVk8/2xEUkAGokozM7SLp9US4lULJ0pXA1/MuVpZ20cGngJDYWVotSg90LbHAjVewVk497qLf9nK/UxoYzMpqWmPDjUCRQeNQVaMglSrRLTXcbWYlzm+MLlvbopagtF43nERlQ4e7xQRSS5k5EkeXOzOGCXNWMK/jTM3+cCIL2lGjWUWjMEZCIymv9nFBgeSPcDHiCjcWy25GfEJq6E5U4ke5YwLaYhxjWHXuVcdkefkTPwIDAQAB";

KeyGenerator keyGen = null;
        try {

            // Generate AES Random secret key
            keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(256);
            SecretKeySpec secretKey = new SecretKeySpec(keyGen.generateKey().getEncoded(), "AES");

            // Get UTF8 encoded data from string to encrypt
            byte[] encodedData = serializedUserAccountToShare.getBytes("UTF-8");

            byte[] encryptedMessage = encryptAES(secretKey, encodedData);

            byte[] encryptedKey = encryptStringWithKey(new String(secretKey.getEncoded(), "UTF-8"), userPublicKi);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
            outputStream.write(encryptedKey);
            outputStream.write(encryptedMessage);
            // Final result to send
            byte dump[] = outputStream.toByteArray();
            // Testing part of the decryption on the Android side
            String decrypted = new String(decryptAES(secretKey.getEncoded(), encryptedMessage));

and the functions I used in the process:

// AES
    private static byte[] encryptAES(SecretKeySpec raw, byte[] clear) throws Exception {
//        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, raw);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

public static PublicKey getKey(String key){
        try{
            byte[] byteKey = Base64.decode(key.getBytes(), Base64.DEFAULT);
            X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
            KeyFactory kf = KeyFactory.getInstance("RSA");

            return kf.generatePublic(X509publicKey);
        }
        catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }

     // RSA
    public byte[] encryptStringWithKey(String text, String key) {
        try {
            // Encrypt the text
            String initialText = text;
            if (initialText.isEmpty()) {
                Toast.makeText(this, "String to encrypt is empty", Toast.LENGTH_LONG).show();
                return new byte[0];
            }

            Cipher input = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            input.init(Cipher.ENCRYPT_MODE, getKey(key));

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            CipherOutputStream cipherOutputStream = new CipherOutputStream(
                    outputStream, input);
            cipherOutputStream.write(initialText.getBytes("UTF-8"));
            cipherOutputStream.close();

            byte[] vals = outputStream.toByteArray();
            outputStream.close();
            return vals;
        } catch (Exception e) {
            Log.e("Exception", Log.getStackTraceString(e));
        }
        return new byte[0];
    }

Thank you.

Update README.md to use correct API

The Complex use case example incorrectly uses the API.

Appears to use outdated X509PublicKey() rather than publicKeyDataX509()

Proposed Complex use case:

let localHeimdall = Heimdall(tagPrefix: "com.example")
if let heimdall = localHeimdall, publicKeyData = heimdall.publicKeyDataX509() {

    var publicKeyString = publicKeyData.base64EncodedStringWithOptions(.allZeros)

    // If you want to make this string URL safe,
    // you have to remember to do the reverse on the other side later
    publicKeyString = publicKeyString.stringByReplacingOccurrencesOfString("/", withString: "_")
    publicKeyString = publicKeyString.stringByReplacingOccurrencesOfString("+", withString: "-")

    println(publicKeyString) // Something along the lines of "MIGfMA0GCSqGSIb3DQEBAQUAA..."

    // Data transmission of public key to the other party
}

Error -9809 when decrtyp data from another device

i created a Heimall and got X509 key.
i share it for another device. another device get it and create another Heimall with X509 key. next from another device encrypt 1 message and send it to first device. on this device decrypt and get err

errSSLCrypto -9809 An underlying cryptographic error was encountered.

why? can you help me?

Compatibility with Crypto++

Hi I just want to know if its RSA encryption / decryption is compatible with Crypto++? We're trying cross platform but its crashing when I'm trying to use his public RSA (from Android-NDK).

Creating Heimdall object and Encryption returning null

Hello,

I have been trying to use your library to create and use public keys from another device that is using the X509 protocol. However I was attempting to create a heimdall object with just a tag so that I could ensure that it works, i instantiated like so:

if let heimdall = Heimdall(publicTag: "com.1066203")

however it returns null, I tried different tags and only a few times could I actually create the object (could not decipher which ones worked because they would not work if ran again). However when I did create the object the encryption method also returned false, I tried to regenerate the key as well. implemented like so:

let testString = "This is a test string"
heimdall.regenerate(1024)

        // Encryption/Decryption
        if let encryptedString = heimdall.encrypt(testString) {
            print(encryptedString) // "cQzaQCQLhAWqkDyPoHnPrpsVh..."

            if let decryptedString = heimdall.decrypt(encryptedString) {
                print(decryptedString) // "This is a test string"
            } else
            {
                print("did not decrypt")
            }
        } else
        {
            print("did not encrypt")
        }

Using breakpoints and the debugger I narrowed it down to the method:

private class func obtainKeyData(tag: String) -> NSData?

always returning nil, and I could not figure out why that is the case. I am relatively new to iOS so hopefully I am just doing something wrong but if not i'd appreciate you taking a look and seeing what could be going wrong. If you would like any other information I will happily give it

Support only public key operations

Some of the operations are also useful when the keychain does not contain the private key. Implement a mechanism for allowing verification and encryption of messages without requiring the presence (or creating) the private key.

Use the same PEM files for every Heimdall instance

Good day Henri,

Thank you for responding to my tweet! I am trying to use the same PEM keys for every instance of Heimdall that I create. All I need to do is encrypt a timestamp with the PRIVATE key to make a simple signature. I haver the PEM of the Public key as well if I need it. I do not mind having to re-make the keys, but I definitely need the private key in a PEM format for the Android version (so if I generate a new key in a new format, I will need to make sure I can convert the new key to a PEM format as well).

Could you please give me an example where the SAME key (preferably a set of PEM keys) are ALWAYS used in Heimdall and result in the same encrypted string? When I do the following:

    if let heimdall = Heimdall(tagPrefix: "www.example.com"){
        if let encryptedString = heimdall.encrypt("test") {
            print("Encrption: [\(encryptedString)]")
        } else {
            print("Encryption error")
        }
    } else {
        print("Init error")
    }

I get a different String every time. I have tried putting the PEM Strings in as parameters:

    if let heim = Heimdall(publicTag: "...", privateTag: "...")

but I get the same result - different Strings every time I run it.

Update for Swift 2.2

The current code base uses C-style for loops, the i++ operator, and var in function parameter declarations. These all now create compiler deprecation warnings.

Heimdall is not working on Xcode 8

Heimdall is not functioning on Xcode 8. Unit tests crash. There seems to be a problem with the obtainKeyData(_ tag: String) function always returning nil.

More specifically, I think this is because SecItemCopyMatching(query as CFDictionary, &keyRef) always returns Item Not Found.

error -9809 when verifying signed string

I am using the below code to sign and verify the signature but getting false always! Digging in further, I found out the error code is -9809 - An underlying cryptographic error was encountered.

Need help in getting this solved please.

Below, am pasting my code -

if let heimdall = Heimdall(tagPrefix: "com.something.myapp") {
            
            let testString = "123456"
            
            if let publicKeyDataX509Value = heimdall.publicKeyDataX509() {
                NSLog("Heimdall Public Key \(publicKeyDataX509Value.base64EncodedString())")
            }
            
            if let signature = heimdall.sign(testString, urlEncode: true) {
                NSLog("signature for 123456 \(signature)")

                var verified = heimdall.verify(testString, signatureBase64: signature, urlEncoded: true)
                NSLog("Verification successful \(verified)") // True
                
                // If someone meddles with the message and the signature becomes invalid
                verified = heimdall.verify(testString + "injected false message",
                                           signatureBase64: signature)
                NSLog("Verification failed \(verified)") // False
            }
        }

Encrypted string is nil with public key data encryption

I invariably get nil when I try to encrypt a String using a public key data object that I have generated. I was hoping you would be able to give me some pointers to how to debug this.

// On device A
let heimdall = Heimdall(tagPrefix: "com.example.app", keySize: 2048)
let publicKeyData = heimdall?.X509PublicKey()
var keyString = publicKeyData?.base64EncodedStringWithOptions(.allZeros)

// then later on Device B
let keyData = NSData(base64EncodedString: keyString, options: NSDataBase64DecodingOptions.allZeros)
let heimdall = Heimdall(publicTag: "com.example.app", publicKeyData: keyData)
let encrypted = heimdall?.encrypt(message, urlEncode: false)

println(encrypted) // nil - :-(

I realize I may be doing something wrong with the tagPrefix/publicTag parameters, but not sure how to use them as the docs are a little unclear.

App containing Heimdall fails to upload to App Store

We get this when uploading with Fastlane pilot:

ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90087: "Unsupported Architectures. The executable for MyApp.app/Frameworks/MyFramework.framework/Frameworks/Heimdall.framework contains unsupported architectures '[x86_64, i386]'."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90087: "Unsupported Architectures. The executable for MyApp.app/Frameworks/MyFramework.framework/Frameworks/JWTDecode.framework contains unsupported architectures '[x86_64, i386]'."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90685: "CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value 'com.hnormak.Heimdall' under the iOS application 'MyApp.app'."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90685: "CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value 'com.auth0.JWTDecode' under the iOS application 'MyApp.app'."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90209: "Invalid Segment Alignment. The app binary at 'MyApp.app/Frameworks/MyFramework.framework/Frameworks/Heimdall.framework/Heimdall' does not have proper segment alignment. Try rebuilding the app with the latest Xcode version."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90209: "Invalid Segment Alignment. The app binary at 'MyApp.app/Frameworks/MyFramework.framework/Frameworks/JWTDecode.framework/JWTDecode' does not have proper segment alignment. Try rebuilding the app with the latest Xcode version."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90205: "Invalid Bundle. The bundle at 'MyApp.app/Frameworks/MyFramework.framework' contains disallowed nested bundles."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90206: "Invalid Bundle. The bundle at 'MyApp.app/Frameworks/MyFramework.framework' contains disallowed file 'Frameworks'."
ERROR [2017-04-18 10:58:33.85]: [Transporter Error Output]: ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."

We're building our app (and expressing our Heimdall dependency) via Carthage, with Xcode 8.3.1. Anyone have any idea what might be going wrong? Anyone successfully uploaded an app with a Heimdall dependency to iTunes Connect post-8.3?

Public Key encryption

Hi,

I have a problem with encrypting a text with an other public key. How do i get the public key from one person, that is a string, in the correct format?

EncryptedMessage always returns nil

if let partnerHeimdall = Heimdall(publicTag: "com.example.partner", publicKeyData: keyData) {
    // Transmit some message to the partner
    let message = "This is a secret message to my partner"
    let encryptedMessage = partnerHeimdall.encrypt(message)

    // Transmit the encryptedMessage back to the origin of the public key
}

Not able to pull 1.1.0

I am trying to use the latest release 1.1.0 in my project, but i am unable to. But this is what i get when trying to install it in my project using cocoapods.

screen shot 2016-10-21 at 16 27 35

Keychain Accessibility

Heimdall doesn't currently have a way to specify accessibility of the key pair entries in the keychain. Unfortunately this means that apps which require access to the keypairs in the background currently won't work correctly while the device is locked (due to the default accessibility of kSecAttrAccessibleWhenUnlocked).

I think it would be helpful to be able to specify a value for kSecAttrAccessible that would override the default. I might have a chance to make a PR soonish, but would appreciate help.

Nil on encrypt on XCode 9.0

It seems that SecItemCopyMatching doesn't return a keyref. Having problems with SwiftyRSA key creation as well, was working before the XCode update. Relevant code:

guard let heimdall = Heimdall(
            publicTag: "sometag",
            publicKeyModulus: modulusData,
            publicKeyExponent: Data(bytes: [0, 1, 0, 1])) else {
                print("Could not obtain encryptor")
                return
        }
guard let cipher = heimdall.encrypt(someData) else {
            print("Could not encrypt data")
            return
        }

Add Error Logging

Anywhere errors might occur it would be nice to log them. I'm currently unable to tell why my call to the failable initializer is returning nil.

Possible octet encoding bug?

Hi
I found this library when looking for ways to implement key pair and pem file generation on iOS. Unfortunately my project is still objective-c so I reimplemented the functions I needed. However, there seems to be an issue in the encodedOctets function line 779. If I understand correctly this should calculate the number of bytes needed to store the number. The current implementation does not seem to do that and will be incorrect for values larger than or equal to 512 (512 will require 3 bytes). I implemented it as
i = log2(value) / 8 + 1

Hope it is of some use and my apologies if I have completely misunderstood something.

Use import Public-Key to verify signature

I try to verify a message with a signature.
I use a public key in Exponent and Modulus representation. This parameters where passed into Heimdall.
I ran into the problem that the message verification failed.

Starting investigations, I noticed, that the byte representation of the original modulus used in Heimdall constructor differs from the output of Heimdall.publicKeyComponents() by one byte.
The Heimdall.publicKeyComponents() modulus byte contains an inserted "0x0" at position index 0.

I noticed this step in https://github.com/henrinormak/Heimdall/blob/master/Heimdall/Heimdall.swift#L828 but I did not get the point of this step.

Why is this 0 added in constructor?
Does this 0 affect the verify() functionality?

Thanks.
Kind regards
Tobias

Generate RSA using Modulus and Exponent

Hi, I need to create an RSA Key providing a modulus and an exponent. Not sure if that is currently possible using Heimdall.
I'll be glad with help of any kind! Thanks

compile error with Carthage

I'm having trouble using the framework with Carthage. I added this line to the file Cartfile:

github "henrinormak/Heimdall"

And the ran carthage update, but I got compilation errors. The error message starts with this:

*** Fetching Heimdall
*** Checking out Heimdall at "1.1.0"
*** xcodebuild output can be found in /var/folders/xv/4249pm313xzftn13dv3ncb940000gn/T/carthage-xcodebuild.fb2uap.log
*** Building scheme "Heimdall-TVOS" in Heimdall.xcodeproj
/Users/jakelim/git/local/PrivacyGuard/Carthage/Checkouts/Heimdall/Heimdall/Heimdall.swift:40:1: error: expressions are not allowed at the top level
/Users/jakelim/git/local/PrivacyGuard/Carthage/Checkouts/Heimdall/Heimdall/Heimdall.swift:40:5: error: consecutive statements on a line must be separated by ';'
/Users/jakelim/git/local/PrivacyGuard/Carthage/Checkouts/Heimdall/Heimdall/Heimdall.swift:41:5: error: expected declaration
/Users/jakelim/git/local/PrivacyGuard/Carthage/Checkouts/Heimdall/Heimdall/Heimdall.swift:41:16: error: consecutive declarations on a line must be separated by ';'

The line 40 in Heimdall.swift starts with the keyword open which is introduced in Swift 3. It seems that Heimdall-TVOS target is still configured to use the legacy Swift syntax, and the Xcode build settings show this as in the screenshot below.

screen shot 2016-10-29 at 5 44 13 pm

To me, it looks like the build setting is the cause of the problem. I'm not sure if there could be further issues. Can this be fixed?

RSA encryption

i've just imported Heimdall as submodule. How can i encrypt my data using RSA encryption

XCode 10: redefinition of module 'CommonCrypto'

I'm trying to run my project with XCode 10 beta, but I get an error saying: redefinition of module 'CommonCrypto'.

Showing All Messages
Failed to emit precompiled header '.../Library/Developer/Xcode/DerivedData/dukzbmbkgxmidoaaqsvrwtawkugp/Build/Intermediates.noindex/PrecompiledHeaders/Bridging-Header-swift_2EL3O7W05IR7C-clang_1MOIT4BKL3MYZ.pch' for bridging header '.../Bridging-Header.h'

Why require iOS 9?

In cde15b3 the Podspec was edited to specify the platform as iOS 9.0. Apparently this means that the host project's "Minimum Deployment Target" must be iOS 9 or greater, or else pod install fails with:

[!] Unable to satisfy the following requirements:

- `Heimdall (~> 0.2.0)` required by `Podfile`

Specs satisfying the `Heimdall (~> 0.2.0)` dependency were found, but they required a higher minimum deployment target.

As far as I know, apps written in Swift 2.0 (with Xcode 7) can support older versions of iOS, such as iOS 8, and as far as I can tell, there were no changes made to this framework to make it specifically incompatible with iOS 8.

If this framework still supports iOS 8, I think this should be changed back.

Use symmetric encryption for long messages

Currently long strings are split into bite sized pieces for the asymmetric RSA encryption. It would be better to research alternatives, such as S/MIME or encrypting the message using a one-off symmetric key that is then encrypted using the current RSA approach.

Add unit tests

Adding unit tests for core functionality will help increase the stability of the codebase. Currently, there are no tests, however, ideally tests would cover the following use cases:

  • Creating Heimdall instances from all possible sources (generating, public key data, public key modulus/exponent)
  • Exporting public key data/modulus/exponent and using the exported result to recreate the instance (partially)
  • Encrypting/Decrypting, making sure the latter is only possible with private keys
  • Signing/Verifying, making sure signing only works properly with private keys

All tests should work for a variety of Heimdall instances (key sizes), as well as for a variety of inputs (short, long, longer).

obtainingKey, SecKeyRef is nil

While obtaining key before encyption,

let status = SecItemCopyMatching(query, &keyRef)
status is 0 but keyRef is nil only on iOS9. it works well on iOS8.

Could you help ?

Thanks

Encryption issue in V1.0.0

Hi,

I use V0.3.0 which can encrypt the text by following code successfully

localHeimdall = Heimdall(tagPrefix: "com.test", keySize: 512)
let encryptedMessage = localHeimdall.encrypt("123")

but the result become nil after I upgrade to V1.0.0

I tried to set a breakpoint in public func encrypt(data: NSData) -> NSData? in"Heimdall.swift", I notice that the status is -50 and will return nil in

if status != noErr {
                    return nil
                }

Could you please help?

65 Compile errors on Xcode 6.1.1 in Swift with Example project

CompileSwift normal x86_64 <path>Heimdall/Heimdall/Heimdall/Heimdall.swift
    cd <path>Heimdall/Heimdall
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file <path>Heimdall/Heimdall/Heimdall/Heimdall.swift -target x86_64-apple-ios8.0 -target-cpu core2 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.1.sdk -I /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Products/Debug-iphonesimulator -I /Users/<user>/Library/Developer/Xcode/DerivedData/modules -F /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Products/Debug-iphonesimulator -g -import-underlying-module -module-cache-path /Users/<user>/Library/Developer/Xcode/DerivedData/ModuleCache -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Heimdall-generated-files.hmap -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Heimdall-own-target-headers.hmap -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Heimdall-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Heimdall-project-headers.hmap -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Products/Debug-iphonesimulator/include -Xcc -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/DerivedSources/x86_64 -Xcc -I/Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -ivfsoverlay -Xcc /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/unextended-module-overlay.yaml -emit-module-doc-path /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Objects-normal/x86_64/Heimdall~partial.swiftdoc -Onone -parse-as-library -module-name Heimdall -emit-module-path /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Objects-normal/x86_64/Heimdall~partial.swiftmodule -serialize-diagnostics-path /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Objects-normal/x86_64/Heimdall.dia -emit-dependencies-path /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Objects-normal/x86_64/Heimdall.d -o /Users/<user>/Library/Developer/Xcode/DerivedData/HeimdallExample-eehzudxaclzvebgffkvuvxmsuoqx/Build/Intermediates/Heimdall.build/Debug-iphonesimulator/Heimdall.build/Objects-normal/x86_64/Heimdall.o

<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:59:73: error: expected '{' after 'if' condition
            if let newData = publicKeyData?.dataByStrippingX509Header() where !existingData.isEqualToData(newData) {
                                                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:59:116: error: braced block of statements is an unused closure
            if let newData = publicKeyData?.dataByStrippingX509Header() where !existingData.isEqualToData(newData) {
                                                                                                                   ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:64:72: error: expected '{' after 'if' condition
        } else if let data = publicKeyData?.dataByStrippingX509Header(), key = Heimdall.insertPublicKey(publicTag, data: data) {
                                                                       ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:64:128: error: braced block of statements is an unused closure
        } else if let data = publicKeyData?.dataByStrippingX509Header(), key = Heimdall.insertPublicKey(publicTag, data: data) {
                                                                                                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:67:10: error: consecutive statements on a line must be separated by ';'
        } else {
         ^
         ;
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:67:11: error: expected expression
        } else {
          ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:67:16: error: braced block of statements is an unused closure
        } else {
               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:138:48: error: expected '{' after 'if' condition
        if let keyData = obtainKeyData(.Public), (modulus, exponent) = keyData.splitIntoComponents() {
                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:138:102: error: braced block of statements is an unused closure
        if let keyData = obtainKeyData(.Public), (modulus, exponent) = keyData.splitIntoComponents() {
                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:160:46: error: expected '{' after 'if' condition
        if let publicKey = obtainKey(.Public), aesKey = Heimdall.generateSymmetricKey(Int(kCCKeySizeAES256)), encrypted = Heimdall.encrypt(string, key: aesKey) {
                                             ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:160:161: error: braced block of statements is an unused closure
        if let publicKey = obtainKey(.Public), aesKey = Heimdall.generateSymmetricKey(Int(kCCKeySizeAES256)), encrypted = Heimdall.encrypt(string, key: aesKey) {
                                                                                                                                                                ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:247:41: error: expected '{' after 'if' condition
        if let key = obtainKey(.Private), messageData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false), hash = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) {
                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:247:194: error: braced block of statements is an unused closure
        if let key = obtainKey(.Private), messageData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false), hash = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) {
                                                                                                                                                                                                 ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:298:96: error: expected '{' after 'if' condition
            if let signature = NSData(base64EncodedString: signatureBase64, options: .allZeros),
                                                                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:300:80: error: braced block of statements is an unused closure
                hashData = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) {
                                                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:371:45: error: expected '{' after 'if' condition
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:371:134: error: braced block of statements is an unused closure
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:381:45: error: expected '{' after 'if' condition
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:381:134: error: braced block of statements is an unused closure
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:407:31: error: expected type after 'as'
                return (ref as! SecKeyRef)
                              ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:407:31: error: expected ',' separator
                return (ref as! SecKeyRef)
                              ^
                              ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:407:31: error: expected expression in list of expressions
                return (ref as! SecKeyRef)
                              ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:407:31: error: expected ',' separator
                return (ref as! SecKeyRef)
                              ^
                              ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:429:61: error: expected type after 'as'
            result = Optional(keyRef?.takeRetainedValue() as! NSData)
                                                            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:429:61: error: expected ',' separator
            result = Optional(keyRef?.takeRetainedValue() as! NSData)
                                                            ^
                                                            ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:429:61: error: expected expression in list of expressions
            result = Optional(keyRef?.takeRetainedValue() as! NSData)
                                                            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:429:61: error: expected ',' separator
            result = Optional(keyRef?.takeRetainedValue() as! NSData)
                                                            ^
                                                            ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:483:74: error: expected type after 'as'
                              kSecPublicKeyAttrs.takeUnretainedValue() as! String: publicAttributes,
                                                                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:483:74: error: expected ',' separator
                              kSecPublicKeyAttrs.takeUnretainedValue() as! String: publicAttributes,
                                                                         ^
                                                                         ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:483:74: error: expected key expression in dictionary literal
                              kSecPublicKeyAttrs.takeUnretainedValue() as! String: publicAttributes,
                                                                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:483:74: error: expected ',' separator
                              kSecPublicKeyAttrs.takeUnretainedValue() as! String: publicAttributes,
                                                                         ^
                                                                         ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:484:75: error: expected type after 'as'
                              kSecPrivateKeyAttrs.takeUnretainedValue() as! String: privateAttributes]
                                                                          ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:484:75: error: expected ',' separator
                              kSecPrivateKeyAttrs.takeUnretainedValue() as! String: privateAttributes]
                                                                          ^
                                                                          ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:484:75: error: expected key expression in dictionary literal
                              kSecPrivateKeyAttrs.takeUnretainedValue() as! String: privateAttributes]
                                                                          ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:484:75: error: expected ',' separator
                              kSecPrivateKeyAttrs.takeUnretainedValue() as! String: privateAttributes]
                                                                          ^
                                                                          ,
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:490:45: error: expected '{' after 'if' condition
                if let publicKey = publicRef, privateKey = privateRef {
                                            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:490:71: error: braced block of statements is an unused closure
                if let publicKey = publicRef, privateKey = privateRef {
                                                                      ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:670:37: error: expected '{' after 'if' condition
            if keyBytes[i++] == 0x02, let modulusLength = NSInteger(octetBytes: keyBytes, startIdx: &i) {
                                    ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:671:68: error: variable used within its own initial value
                let modulus = self.subdataWithRange(NSMakeRange(i, modulusLength))
                                                                   ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:672:22: error: variable used within its own initial value
                i += modulusLength
                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:675:41: error: expected '{' after 'if' condition
                if keyBytes[i++] == 0x02, let exponentLength = NSInteger(octetBytes: keyBytes, startIdx: &i) {
                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:676:73: error: variable used within its own initial value
                    let exponent = self.subdataWithRange(NSMakeRange(i, exponentLength))
                                                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:677:26: error: variable used within its own initial value
                    i += exponentLength
                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:60:53: error: use of unresolved identifier 'newData'
                Heimdall.updateKey(publicTag, data: newData)
                                                    ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:64:128: error: expression resolves to an unused function
        } else if let data = publicKeyData?.dataByStrippingX509Header(), key = Heimdall.insertPublicKey(publicTag, data: data) {
                                                                                                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:67:16: error: type of expression is ambiguous without more context
        } else {
               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:138:102: error: type of expression is ambiguous without more context
        if let keyData = obtainKeyData(.Public), (modulus, exponent) = keyData.splitIntoComponents() {
                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:160:161: error: type of expression is ambiguous without more context
        if let publicKey = obtainKey(.Public), aesKey = Heimdall.generateSymmetricKey(Int(kCCKeySizeAES256)), encrypted = Heimdall.encrypt(string, key: aesKey) {
                                                                                                                                                                ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:212:36: error: could not find an overload for 'init' that accepts the supplied arguments
                let keyData = data.subdataWithRange(NSRange(location: 0, length: blockSize))
                              ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:213:40: error: could not find an overload for '-' that accepts the supplied arguments
                let messageData = data.subdataWithRange(NSRange(location: blockSize, length: data.length - blockSize))
                                  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:216:56: error: extra argument 'length' in call
                if let decryptedKeyData = NSMutableData(length: blockSize) {
                                                       ^        ~~~~~~~~~
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:247:194: error: type of expression is ambiguous without more context
        if let key = obtainKey(.Private), messageData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false), hash = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) {
                                                                                                                                                                                                 ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:300:80: error: type of expression is ambiguous without more context
                hashData = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) {
                                                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:371:134: error: type of expression is ambiguous without more context
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:381:134: error: type of expression is ambiguous without more context
        } else if let tag = self.privateTag where key == .Private && self.scope & ScopeOptions.PrivateKey == ScopeOptions.PrivateKey {
                                                                                                                                     ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:401:13: warning: immutable value is default initialized and can never be changed
        let result: SecKeyRef?
            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:407:24: error: '()' is not convertible to 'SecKeyRef'
                return (ref as! SecKeyRef)
                       ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:410:20: error: cannot assign to 'let' value 'result'
            result = nil
            ~~~~~~ ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:425:13: warning: immutable value is default initialized and can never be changed
        let result: NSData?
            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:429:20: error: cannot assign to 'let' value 'result'
            result = Optional(keyRef?.takeRetainedValue() as! NSData)
            ~~~~~~ ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:431:20: error: cannot assign to 'let' value 'result'
            result = nil
            ~~~~~~ ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:463:48: error: use of unresolved identifier '>?'
        var persistentRef = Unmanaged<AnyObject>?()
                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:463:48: error: operator is not a known binary operator
        var persistentRef = Unmanaged<AnyObject>?()
                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:463:48: error: operator is not a known binary operator
        var persistentRef = Unmanaged<AnyObject>?()
                                               ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:464:13: warning: immutable value is default initialized and can never be changed
        let result: SecKeyRef?
            ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:486:41: error: use of unresolved identifier '>?'
        var publicRef = Unmanaged<SecKey>?()
                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:486:41: error: operator is not a known binary operator
        var publicRef = Unmanaged<SecKey>?()
                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:486:41: error: operator is not a known binary operator
        var publicRef = Unmanaged<SecKey>?()
                                        ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:487:42: error: use of unresolved identifier '>?'
        var privateRef = Unmanaged<SecKey>?()
                                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:487:42: error: operator is not a known binary operator
        var privateRef = Unmanaged<SecKey>?()
                                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:487:42: error: operator is not a known binary operator
        var privateRef = Unmanaged<SecKey>?()
                                         ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:502:47: error: 'Int' is not convertible to 'UInt'
        SecRandomCopyBytes(kSecRandomDefault, keySize, &result)
                                              ^
Security.count:1:5: note: in initialization of parameter 'count'
let count: UInt
    ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:522:180: error: 'Int' is not convertible to 'UInt'
                let status = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128), CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding), keyData, keyLength, nil, data, dataLength, encryptedData, encryptedDataLength, &encryptedLength)
                                                                                                                                                                                   ^
CommonCrypto.dataInLength:1:5: note: in initialization of parameter 'dataInLength'
let dataInLength: UInt
    ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:547:185: error: 'Int' is not convertible to 'UInt'
            let status = CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmAES128), CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding), keyData, keyLength, nil, encryptedData, encryptedDataLength, decryptedData, decryptedDataLength, &decryptedLength)
                                                                                                                                                                                        ^
CommonCrypto.dataInLength:1:5: note: in initialization of parameter 'dataInLength'
let dataInLength: UInt
    ^
<path>Heimdall/Heimdall/Heimdall/Heimdall.swift:670:68: error: extra argument 'octetBytes' in call
            if keyBytes[i++] == 0x02, let modulusLength = NSInteger(octetBytes: keyBytes, startIdx: &i) {

intermittent failure decrypting... (???)

Not really sure how to perfectly describe my problem =(. I am using the latest version available via cocoapods and latest Swift. I am encrypting both text, e.g. String = "foo" and also images after base64 encoding them e.g.
let _imageData = UIImageJPEGRepresentation(image, compressionFactor)
let _encodedString = _imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())

I use a 2048 size key e.g. Heimdall(tagPrefix: key, keySize: 2048) and when I encrypt and decrypt I use urlEncode: false since the data is stored in a back end that doesn't need url encoding.
I decrypt simply by:
if let clearText = my_Heimdall_instance.decrypt(encrypted_text, urlEncoded: false) as String? { ...}
So far so good. It's a chat application. it works great! except every now and again, seemingly without any pattern, decryption fails and returns nil. It's almost random and happens once every 20 to 100 messages. Sometimes with plain text messages, sometimes with images. I suspect some weird boundary condition (padding?) but I can't figure it out! The encrypted content looks normal and the length seems reasonable

Any ideas?? [there may be a small reward for the first person to solve it!]

Thanks! =)

ps: FWIW, here is an example of an encrypted message that failed to decrypt. It's a few simple words as a String:
jNCNYe8NPgqs3jspfGGiOwa/AkRb5PBWSp0FFvVdvMrMU50/0ti8j4SpYF+/OlcaeorpItuqEymU/mNB9PhHaV7IhxTPk8STcEs0o8KynHq1l7bHQ6gkHCMwhTxgNBeB+Mvctv5Pxxxg3+ESUmCKMH4G9+skC63Mamcm5BIRqokoL3lxnHaz77j0N09jP0rAkBY0jwN0myGrp2JV1cqLzzkWkTOYFkzgReMqRgrf3c2c9/vrRCPLk9umGGFq/YfCZXfpFja6C3OwPulgoKFxu/qX2hYAUZdJrZ0ao1/bL+xkSLvnOw/dXaR3FAxggFhzvbb/7+AVbnW3clvOF2gzLN05igEB6vxQuX0rQ9QLRop5hgR157LepY+EJtwBnSocPeYJ94MqoV0IeuFuevhuOXycAcyGwTHosdQX4pl7JzRs1oZR7wLJJgV4UDYF/uVXhp3X744+doefZsOvMnjddA==

Cocoapods: Absolute path in modulemap causes build issues on some machines

In all modulemap files e.g.:
https://github.com/henrinormak/Heimdall/blob/master/CommonCrypto/iphonesimulator.modulemap

I am not too deeply knowledgable how Cocoapods exactly works but I would hope there is a better way to do this. Something like this would be my first guess:
https://github.com/onmyway133/Arcane/blob/master/Sources/CCommonCrypto/module.modulemap

Basically my problem is that while I can adjust the path locally for my system, the Pods are not committed to Git so Jenkins will never be able to build (multiple Xcode installations with different paths).

Thanks for any suggestions.

Xcode Warning

It would be nice not to see this warning (current release 1.1.3)

../Pods/Heimdall/Heimdall/Heimdall.swift:278:91: Conditional downcast from 'NSString?' to 'String' is a bridging conversion; did you mean to use 'as'?

Compilation error - redefinition of module CommonCrypto

Hey
I've just installed Heimdall in my project using cocoapods. When I've tried to compile it using XCode 7.3, I've got the following error:

path-to-project/Pods/Heimdall/CommonCrypto/appletvsimulator/module.modulemap:1:8: Redefinition of module 'CommonCrypto'
path-to-project/Pods/Heimdall/CommonCrypto/appletvos/module.modulemap:1:8: Previously defined here

it happen also for the iphone simulator map. I think this is because I have another pod (Branch that depend on CommonCrypto, but I am not sure what to do in order to solve it.

Hope you could help with this mysterious error,
Omer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.