0001
0025 import COpenSSL
0026 @_exported import Data
0027
0028 public enum HashType| Hash.swift:32 | internal extension HashType { |
{
0029 case SHA1| Hash.swift:35 | case .SHA1: |
| Hash.swift:50 | case .SHA1: |
| Hash.swift:65 | case .SHA1: |
, SHA224| Hash.swift:37 | case .SHA224: |
| Hash.swift:52 | case .SHA224: |
| Hash.swift:67 | case .SHA224: |
, SHA256| Hash.swift:39 | case .SHA256: |
| Hash.swift:54 | case .SHA256: |
| Hash.swift:69 | case .SHA256: |
, SHA384| Hash.swift:41 | case .SHA384: |
| Hash.swift:56 | case .SHA384: |
| Hash.swift:71 | case .SHA384: |
, SHA512| Hash.swift:43 | case .SHA512: |
| Hash.swift:58 | case .SHA512: |
| Hash.swift:73 | case .SHA512: |
0030 }
0031
0032 internal extension HashType {
0033 var digestLength: Int {
0034 switch self {
0035 case .SHA1:
0036 return Int(SHA_DIGEST_LENGTH)
0037 case .SHA224:
0038 return Int(SHA224_DIGEST_LENGTH)
0039 case .SHA256:
0040 return Int(SHA256_DIGEST_LENGTH)
0041 case .SHA384:
0042 return Int(SHA384_DIGEST_LENGTH)
0043 case .SHA512:
0044 return Int(SHA512_DIGEST_LENGTH)
0045 }
0046 }
0047
0048 var function: ((UnsafePointer<UInt8>, Int, UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8>) {
0049 switch self {
0050 case .SHA1:
0051 return COpenSSL.SHA1
0052 case .SHA224:
0053 return COpenSSL.SHA224
0054 case .SHA256:
0055 return COpenSSL.SHA256
0056 case .SHA384:
0057 return COpenSSL.SHA384
0058 case .SHA512:
0059 return COpenSSL.SHA512
0060 }
0061 }
0062
0063 var evp: UnsafePointer<EVP_MD> {
0064 switch self {
0065 case .SHA1:
0066 return EVP_sha1()
0067 case .SHA224:
0068 return EVP_sha224()
0069 case .SHA256:
0070 return EVP_sha256()
0071 case .SHA384:
0072 return EVP_sha384()
0073 case .SHA512:
0074 return EVP_sha512()
0075 }
0076 }
0077 }
0078
0079 public struct Hash {
0080
0081 public enum Error| Hash.swift:124 | throw Error.Error(description: lastSSLErrorDescription) |
: ErrorType {
0082 case Error| Hash.swift:124 | throw Error.Error(description: lastSSLErrorDescription) |
(description: String)
0083 }
0084
0085
0087 public static func hash(type: HashType, message: Data) -> Data {
0088 OpenSSL.initialize()
0089
0090 var hashBuf = Data.bufferWithSize(Int(type.digestLength))
0091 message.withUnsafeBufferPointer { ptr in
0092 hashBuf.withUnsafeMutableBufferPointer { bufPtr in
0093 type.function(ptr.baseAddress, ptr.count, bufPtr.baseAddress)
0094 }
0095 }
0096 return hashBuf
0097 }
0098
0099
0101 public static func hmac(type: HashType, key: Data, message: Data) -> Data {
0102 OpenSSL.initialize()
0103
0104 var resultLen: UInt32 = 0
0105 let result = UnsafeMutablePointer<Byte>.alloc(Int(EVP_MAX_MD_SIZE))
0106 key.withUnsafeBufferPointer { keyPtr in
0107 message.withUnsafeBufferPointer { msgPtr in
0108 COpenSSL.HMAC(type.evp, keyPtr.baseAddress, Int32(key.count), msgPtr.baseAddress, msgPtr.count, result, &resultLen)
0109 }
0110 }
0111 let data = Data(Array(UnsafeBufferPointer<Byte>(start: result, count: Int(resultLen))))
0112 result.destroy(Int(resultLen))
0113 result.dealloc(Int(EVP_MAX_MD_SIZE))
0114 return data
0115 }
0116
0117
0119 public static func rsa(hashType: HashType, key: Key, message: Data) throws -> Data {
0120 OpenSSL.initialize()
0121
0122 let ctx = EVP_MD_CTX_create()
0123 guard ctx != nil else {
0124 throw Error.Error(description: lastSSLErrorDescription)
0125 }
0126
0127 return message.withUnsafeBufferPointer { digestPtr in
0128 EVP_DigestInit_ex(ctx, hashType.evp, nil)
0129 EVP_DigestUpdate(ctx, UnsafePointer<Void>(digestPtr.baseAddress), digestPtr.count)
0130 var signLen: UInt32 = 0
0131 var buf = Data.bufferWithSize(Int(EVP_PKEY_size(key.key)))
0132 buf.withUnsafeMutableBufferPointer { ptr in
0133 EVP_SignFinal(ctx, ptr.baseAddress, &signLen, key.key)
0134 }
0135 return buf.prefix(Int(signLen))
0136 }
0137 }
0138
0139 }
0140