Skip to content

Commit

Permalink
Merge pull request #10 from gtaban/linuxTestSign
Browse files Browse the repository at this point in the history
Linux sign/verify support.
  • Loading branch information
billabt authored Dec 21, 2017
2 parents 62df3fb + 944041a commit 7f38575
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 12 deletions.
101 changes: 93 additions & 8 deletions Sources/CryptorRSA/CryptorRSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

import Foundation

#if os(Linux)
import OpenSSL
#endif

// MARK: -

// MARK: -
Expand Down Expand Up @@ -313,13 +317,55 @@ public class CryptorRSA {
}

#if os(Linux)

throw Error(code: ERR_NOT_IMPLEMENTED, reason: "Not implemented yet.")


// EVP_MD_CTX_create() renamed to _new
let md_ctx = EVP_MD_CTX_create()
defer {
EVP_MD_CTX_destroy(md_ctx)
}

let (md, _) = algorithm.algorithmForSignature // (md, padding)
// TODO. Add the padding option. Right now we are ignoring it

// convert RSA key to EVP
let evp_key = EVP_PKEY_new()
var rc = EVP_PKEY_set1_RSA(evp_key, key.reference)
guard rc == 1 else {
let source = "Couldn't create key reference from key data"
if let reason = CryptorRSA.getLastError(source: source) {

throw Error(code: ERR_ADD_KEY, reason: reason)
}
throw Error(code: ERR_ADD_KEY, reason: source + ": No OpenSSL error reported.")
}

// Determine the size of the signature
var sig_len: Int = Int(EVP_PKEY_size(evp_key))
let sig = UnsafeMutablePointer<UInt8>.allocate(capacity: sig_len)

EVP_DigestSignInit(md_ctx, nil, md, nil, evp_key)

// convert Data to UnsafeRawPointer!
_ = self.data.withUnsafeBytes({ (message: UnsafePointer<UInt8>) -> Int32 in
return EVP_DigestUpdate(md_ctx, message, self.data.count)
})

rc = EVP_DigestSignFinal(md_ctx, sig, &sig_len)
guard rc == 1 else {
let source = "Couldn't create key reference from key data"
if let reason = CryptorRSA.getLastError(source: source) {

throw Error(code: ERR_SIGNING_FAILED, reason: reason)
}
throw Error(code: ERR_SIGNING_FAILED, reason: source + ": No OpenSSL error reported.")
}

return SignedData(with: Data(bytes: sig, count: sig_len))

#else

var response: Unmanaged<CFError>? = nil
let sData = SecKeyCreateSignature(key.reference, algorithm.alogrithmForSignature, self.data as CFData, &response)
let sData = SecKeyCreateSignature(key.reference, algorithm.algorithmForSignature, self.data as CFData, &response)
if response != nil {

guard let error = response?.takeRetainedValue() else {
Expand Down Expand Up @@ -366,20 +412,59 @@ public class CryptorRSA {

#if os(Linux)

throw Error(code: ERR_NOT_IMPLEMENTED, reason: "Not implemented yet.")
let md_ctx = EVP_MD_CTX_create()
defer {
EVP_MD_CTX_destroy(md_ctx)
}

let (md, _) = algorithm.algorithmForSignature // (md, padding)
// TODO. Add the padding option. Right now we are ignoring it

// convert RSA key to EVP
let evp_key = EVP_PKEY_new()
var rc = EVP_PKEY_set1_RSA(evp_key, key.reference)
guard rc == 1 else {
let source = "Couldn't create key reference from key data"
if let reason = CryptorRSA.getLastError(source: source) {

throw Error(code: ERR_ADD_KEY, reason: reason)
}
throw Error(code: ERR_ADD_KEY, reason: source + ": No OpenSSL error reported.")
}

EVP_DigestVerifyInit(md_ctx, nil, md, nil, evp_key)

rc = self.data.withUnsafeBytes({ (message: UnsafePointer<UInt8>) -> Int32 in
return EVP_DigestUpdate(md_ctx, message, self.data.count)
})
guard rc == 1 else {
let source = "Couldn't create key reference from key data"
if let reason = CryptorRSA.getLastError(source: source) {

throw Error(code: ERR_VERIFICATION_FAILED, reason: reason)
}
throw Error(code: ERR_VERIFICATION_FAILED, reason: source + ": No OpenSSL error reported.")
}

// Unlike other return values above, this return indicates if signature verifies or not
rc = signature.data.withUnsafeBytes({ (sig: UnsafePointer<UInt8>) -> Int32 in
return EVP_DigestVerifyFinal(md_ctx, sig, signature.data.count)
})

return (rc == 1) ? true : false

#else

var response: Unmanaged<CFError>? = nil
let result = SecKeyVerifySignature(key.reference, algorithm.alogrithmForSignature, self.data as CFData, signature.data as CFData, &response)
let result = SecKeyVerifySignature(key.reference, algorithm.algorithmForSignature, self.data as CFData, signature.data as CFData, &response)
if response != nil {

guard let error = response?.takeRetainedValue() else {

throw Error(code: CryptorRSA.ERR_SIGNING_FAILED, reason: "Verification failed. Unable to determine error.")
throw Error(code: CryptorRSA.ERR_VERIFICATION_FAILED, reason: "Verification failed. Unable to determine error.")
}

throw Error(code: CryptorRSA.ERR_SIGNING_FAILED, reason: "Verification failed with error: \(error)")
throw Error(code: CryptorRSA.ERR_VERIFICATION_FAILED, reason: "Verification failed with error: \(error)")
}

return result
Expand Down
27 changes: 25 additions & 2 deletions Sources/CryptorRSA/CryptorRSADigest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,33 @@ public extension Data {
#endif
}

#if !os(Linux)
#if os(Linux)
public var algorithmForSignature: (UnsafePointer<EVP_MD>, Int32) {

switch self {

case .sha1:
return (EVP_sha1(), RSA_PKCS1_PADDING)

case .sha224:
return (EVP_sha224(), RSA_PKCS1_PADDING)

case .sha256:
return (EVP_sha256(), RSA_PKCS1_PADDING)

case .sha384:
return (EVP_sha384(), RSA_PKCS1_PADDING)

case .sha512:
return (EVP_sha512(), RSA_PKCS1_PADDING)

}
}

#else

@available(macOS 10.12, iOS 10.0, *)
public var alogrithmForSignature: SecKeyAlgorithm {
public var algorithmForSignature: SecKeyAlgorithm {

switch self {

Expand Down
4 changes: 2 additions & 2 deletions Tests/CryptorRSATests/CryptorRSATests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ class CryptorRSATests: XCTestCase {
// ("test_simpleEncryption", test_simpleEncryption),
// ("test_longStringEncryption", test_longStringEncryption),
// ("test_randomByteEncryption", test_randomByteEncryption),
// ("test_signVerifyAllDigestTypes", test_signVerifyAllDigestTypes),
// ("test_signVerifyBase64", test_signVerifyBase64),
("test_signVerifyAllDigestTypes", test_signVerifyAllDigestTypes),
("test_signVerifyBase64", test_signVerifyBase64),
]
}
}
Expand Down

0 comments on commit 7f38575

Please sign in to comment.