Skip to content

Commit

Permalink
Merge pull request #11 from gtaban/linuxTestSign
Browse files Browse the repository at this point in the history
Update RSA Signing to add padding option, and use correct function to get sig size
  • Loading branch information
billabt authored Jan 12, 2018
2 parents 689dc75 + abad813 commit fdbb74f
Showing 1 changed file with 32 additions and 20 deletions.
52 changes: 32 additions & 20 deletions Sources/CryptorRSA/CryptorRSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,12 @@ public class CryptorRSA {

#if os(Linux)

// 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)
Expand All @@ -340,27 +336,37 @@ public class CryptorRSA {
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)
let (md, padding) = algorithm.algorithmForSignature

// Provide a pkey_ctx to EVP_DigestSignInit so that the EVP_PKEY_CTX of the signing operation
// is written to it, to allow alternative signing options to be set
var pkey_ctx = EVP_PKEY_CTX_new(evp_key, nil)

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

// Now that Init has initialized pkey_ctx, set the padding option
EVP_PKEY_CTX_ctrl(pkey_ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, padding, nil)

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)
})

// Determine the size of the actual signature
var sig_len: Int = 0
EVP_DigestSignFinal(md_ctx, nil, &sig_len)
let sig = UnsafeMutablePointer<UInt8>.allocate(capacity: sig_len)

rc = EVP_DigestSignFinal(md_ctx, sig, &sig_len)
guard rc == 1 else {
let source = "Couldn't create key reference from key data"
guard rc == 1, sig_len > 0 else {
let source = "Signing failed."
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
Expand Down Expand Up @@ -417,9 +423,6 @@ public class CryptorRSA {
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()
Expand All @@ -433,13 +436,22 @@ public class CryptorRSA {
throw Error(code: ERR_ADD_KEY, reason: source + ": No OpenSSL error reported.")
}

EVP_DigestVerifyInit(md_ctx, nil, md, nil, evp_key)
let (md, padding) = algorithm.algorithmForSignature

// Provide a pkey_ctx to EVP_DigestSignInit so that the EVP_PKEY_CTX of the signing operation
// is written to it, to allow alternative signing options to be set
var pkey_ctx = EVP_PKEY_CTX_new(evp_key, nil)

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

// Now that EVP_DigestVerifyInit has initialized pkey_ctx, set the padding option
EVP_PKEY_CTX_ctrl(pkey_ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, padding, nil)

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"
let source = "Signature verification failed."
if let reason = CryptorRSA.getLastError(source: source) {

throw Error(code: ERR_VERIFICATION_FAILED, reason: reason)
Expand All @@ -462,10 +474,10 @@ public class CryptorRSA {

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

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

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

return result
Expand Down

0 comments on commit fdbb74f

Please sign in to comment.