0001    // Hash.swift
0002    //
0003    // The MIT License (MIT)
0004    //
0005    // Copyright (c) 2015 Zewo
0006    //
0007    // Permission is hereby granted, free of charge, to any person obtaining a copy
0008    // of this software and associated documentation files (the "Software"), to deal
0009    // in the Software without restriction, including without limitation the rights
0010    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0011    // copies of the Software, and to permit persons to whom the Software is
0012    // furnished to do so, subject to the following conditions:
0013    //
0014    // The above copyright notice and this permission notice shall be included in all
0015    // copies or substantial portions of the Software.
0016    //
0017    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0018    // IMPLIED, INCLUDINbG BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0019    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0020    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0021    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0022    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0023    // SOFTWARE.
0024    
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 // MARK: - Hash 0086 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 // MARK: - HMAC 0100 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 // MARK: - RSA 0118 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