Added SymmetricKey

This commit is contained in:
Adam Fowler 2020-02-01 11:06:51 +00:00
parent 81dc1183ed
commit 38ab4efd6c
4 changed files with 42 additions and 14 deletions

View File

@ -15,11 +15,11 @@ import CommonCrypto
/// Object generating HMAC for data block given a symmetric key
public struct HMAC<H: CCHashFunction> {
let key: [UInt8]
let key: SymmetricKey
var context: CCHmacContext
/// return authentication code for data block given a symmetric key
public static func authenticationCode<D : DataProtocol>(for data: D, using key: [UInt8]) -> HashAuthenticationCode {
public static func authenticationCode<D : DataProtocol>(for data: D, using key: SymmetricKey) -> HashAuthenticationCode {
var hmac = HMAC(key: key)
hmac.update(data: data)
return hmac.finalize()
@ -42,7 +42,7 @@ public struct HMAC<H: CCHashFunction> {
extension HMAC {
/// initialize HMAC with symmetric key
public init(key: [UInt8]) {
public init(key: SymmetricKey) {
self.key = key
self.context = CCHmacContext()
self.initialize()
@ -50,7 +50,7 @@ extension HMAC {
/// initialize HMAC calculation
mutating func initialize() {
CCHmacInit(&context, H.algorithm, key, key.count)
CCHmacInit(&context, H.algorithm, key.bytes, key.bytes.count)
}
/// update HMAC calculation with a buffer
@ -72,11 +72,11 @@ import CAWSCrypto
public struct HMAC<H: OpenSSLHashFunction> {
let key: [UInt8]
let key: SymmetricKey
var context: OpaquePointer
/// return authentication code for data block given a symmetric key
public static func authenticationCode<D : DataProtocol>(for data: D, using key: [UInt8]) -> HashAuthenticationCode {
public static func authenticationCode<D : DataProtocol>(for data: D, using key: SymmetricKey) -> HashAuthenticationCode {
var hmac = HMAC(key: key)
hmac.update(data: data)
return hmac.finalize()
@ -99,7 +99,7 @@ public struct HMAC<H: OpenSSLHashFunction> {
extension HMAC {
/// initialize HMAC with symmetric key
public init(key: [UInt8]) {
public init(key: SymmetricKey) {
self.key = key
self.context = AWSCRYPTO_HMAC_CTX_new()
self.initialize()
@ -107,7 +107,7 @@ extension HMAC {
/// initialize HMAC calculation
mutating func initialize() {
HMAC_Init_ex(context, key, Int32(key.count), H.algorithm, nil)
HMAC_Init_ex(context, key.bytes, Int32(key.bytes.count), H.algorithm, nil)
}
/// update HMAC calculation with a buffer

View File

@ -0,0 +1,28 @@
// SymmetricKey.swift
// based on the Vapor/open-crypto project which tries to replicate the CryptoKit framework interface
// written by AdamFowler 2020/01/30
import protocol Foundation.ContiguousBytes
/// Symmetric key object
public struct SymmetricKey: ContiguousBytes {
let bytes: [UInt8]
public var bitCount: Int {
return self.bytes.count * 8
}
public init<D>(data: D) where D : ContiguousBytes {
let bytes = data.withUnsafeBytes { buffer in
return [UInt8](buffer)
}
self.init(bytes: bytes)
}
public init(bytes: [UInt8]) {
self.bytes = bytes
}
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try self.bytes.withUnsafeBytes(body)
}
}

View File

@ -145,11 +145,11 @@ public struct AWSSigner {
// Stage 3 Calculating signature as in https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
func signature(signingData: SigningData) -> String {
let kDate = HMAC<SHA256>.authenticationCode(for: Data(signingData.date.utf8), using: Array("AWS4\(credentials.secretAccessKey)".utf8))
let kRegion = HMAC<SHA256>.authenticationCode(for: Data(region.utf8), using: kDate.bytes)
let kService = HMAC<SHA256>.authenticationCode(for: Data(name.utf8), using: kRegion.bytes)
let kSigning = HMAC<SHA256>.authenticationCode(for: Data("aws4_request".utf8), using: kService.bytes)
let kSignature = HMAC<SHA256>.authenticationCode(for: stringToSign(signingData: signingData), using: kSigning.bytes)
let kDate = HMAC<SHA256>.authenticationCode(for: Data(signingData.date.utf8), using: SymmetricKey(data: Array("AWS4\(credentials.secretAccessKey)".utf8)))
let kRegion = HMAC<SHA256>.authenticationCode(for: Data(region.utf8), using: SymmetricKey(data: kDate))
let kService = HMAC<SHA256>.authenticationCode(for: Data(name.utf8), using: SymmetricKey(data: kRegion))
let kSigning = HMAC<SHA256>.authenticationCode(for: Data("aws4_request".utf8), using: SymmetricKey(data: kService))
let kSignature = HMAC<SHA256>.authenticationCode(for: stringToSign(signingData: signingData), using: SymmetricKey(data: kSigning))
return kSignature.description
}

View File

@ -38,7 +38,7 @@ final class AWSCryptoTests: XCTestCase {
func testHMAC() {
let data = createRandomBuffer(1, 91, size: 347237)
let key = createRandomBuffer(102, 3, size: 32)
let authenticationKey = HMAC<SHA256>.authenticationCode(for: data, using: key)
let authenticationKey = HMAC<SHA256>.authenticationCode(for: data, using: SymmetricKey(data: key))
print(authenticationKey)
XCTAssertEqual(authenticationKey.description, "ddec250211f1b546254bab3fb027af1acc4842898e8af6eeadcdbf8e2c6c1ff5")
}