module Network.TLS.Extra.Cipher
(
ciphersuite_all
, ciphersuite_medium
, ciphersuite_strong
, ciphersuite_unencrypted
, cipher_null_null
, cipher_null_SHA1
, cipher_null_MD5
, cipher_RC4_128_MD5
, cipher_RC4_128_SHA1
, cipher_AES128_SHA1
, cipher_AES256_SHA1
, cipher_AES128_SHA256
, cipher_AES256_SHA256
) where
import qualified Data.Vector.Unboxed as Vector (fromList, toList)
import qualified Data.ByteString as B
import Network.TLS (Version(..))
import Network.TLS.Cipher
import qualified Crypto.Cipher.RC4 as RC4
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Crypto.Hash.SHA1 as SHA1
import qualified Crypto.Hash.MD5 as MD5
#ifdef CIPHER_AES
import qualified "cipher-aes" Crypto.Cipher.AES as AES
aes_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes_cbc_encrypt key iv d = AES.encryptCBC (AES.initKey key) (AES.IV iv) d
aes_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes_cbc_decrypt key iv d = AES.decryptCBC (AES.initKey key) (AES.IV iv) d
aes128_cbc_encrypt = aes_cbc_encrypt
aes128_cbc_decrypt = aes_cbc_decrypt
aes256_cbc_encrypt = aes_cbc_encrypt
aes256_cbc_decrypt = aes_cbc_decrypt
#else
import qualified "cryptocipher" Crypto.Cipher.AES as AES
aes128_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes128_cbc_encrypt key iv d = AES.encryptCBC pkey iv d
where (Right pkey) = AES.initKey128 key
aes128_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes128_cbc_decrypt key iv d = AES.decryptCBC pkey iv d
where (Right pkey) = AES.initKey128 key
aes256_cbc_encrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes256_cbc_encrypt key iv d = AES.encryptCBC pkey iv d
where (Right pkey) = AES.initKey256 key
aes256_cbc_decrypt :: Key -> IV -> B.ByteString -> B.ByteString
aes256_cbc_decrypt key iv d = AES.decryptCBC pkey iv d
where (Right pkey) = AES.initKey256 key
#endif
toIV :: RC4.Ctx -> IV
toIV (v, x, y) = B.pack (x : y : Vector.toList v)
toCtx :: IV -> RC4.Ctx
toCtx iv =
case B.unpack iv of
x:y:l -> (Vector.fromList l, x, y)
_ -> (Vector.fromList [], 0, 0)
initF_rc4 :: Key -> IV
initF_rc4 key = toIV $ RC4.initCtx (B.unpack key)
encryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV)
encryptF_rc4 iv d = (\(ctx, e) -> (e, toIV ctx)) $ RC4.encrypt (toCtx iv) d
decryptF_rc4 :: IV -> B.ByteString -> (B.ByteString, IV)
decryptF_rc4 iv e = (\(ctx, d) -> (d, toIV ctx)) $ RC4.decrypt (toCtx iv) e
ciphersuite_all :: [Cipher]
ciphersuite_all =
[ cipher_AES128_SHA256, cipher_AES256_SHA256
, cipher_AES128_SHA1, cipher_AES256_SHA1
, cipher_RC4_128_SHA1, cipher_RC4_128_MD5
]
ciphersuite_medium :: [Cipher]
ciphersuite_medium = [cipher_RC4_128_MD5, cipher_RC4_128_SHA1, cipher_AES128_SHA1, cipher_AES256_SHA1]
ciphersuite_strong :: [Cipher]
ciphersuite_strong = [cipher_AES256_SHA256, cipher_AES256_SHA1]
ciphersuite_unencrypted :: [Cipher]
ciphersuite_unencrypted = [cipher_null_MD5, cipher_null_SHA1]
bulk_null = Bulk
{ bulkName = "null"
, bulkKeySize = 0
, bulkIVSize = 0
, bulkBlockSize = 0
, bulkF = BulkNoneF
}
bulk_rc4 = Bulk
{ bulkName = "RC4-128"
, bulkKeySize = 16
, bulkIVSize = 0
, bulkBlockSize = 0
, bulkF = BulkStreamF initF_rc4 encryptF_rc4 decryptF_rc4
}
bulk_aes128 = Bulk
{ bulkName = "AES128"
, bulkKeySize = 16
, bulkIVSize = 16
, bulkBlockSize = 16
, bulkF = BulkBlockF aes128_cbc_encrypt aes128_cbc_decrypt
}
bulk_aes256 = Bulk
{ bulkName = "AES256"
, bulkKeySize = 32
, bulkIVSize = 16
, bulkBlockSize = 16
, bulkF = BulkBlockF aes256_cbc_encrypt aes256_cbc_decrypt
}
hash_md5 = Hash
{ hashName = "MD5"
, hashSize = 16
, hashF = MD5.hash
}
hash_sha1 = Hash
{ hashName = "SHA1"
, hashSize = 20
, hashF = SHA1.hash
}
hash_sha256 = Hash
{ hashName = "SHA256"
, hashSize = 32
, hashF = SHA256.hash
}
hash_null = Hash
{ hashName = "null"
, hashSize = 0
, hashF = const B.empty
}
cipher_null_null :: Cipher
cipher_null_null = Cipher
{ cipherID = 0x0
, cipherName = "null-null"
, cipherBulk = bulk_null
, cipherHash = hash_null
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
cipher_null_MD5 :: Cipher
cipher_null_MD5 = Cipher
{ cipherID = 0x1
, cipherName = "RSA-null-MD5"
, cipherBulk = bulk_null
, cipherHash = hash_md5
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
cipher_null_SHA1 :: Cipher
cipher_null_SHA1 = Cipher
{ cipherID = 0x2
, cipherName = "RSA-null-SHA1"
, cipherBulk = bulk_null
, cipherHash = hash_sha1
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
cipher_RC4_128_MD5 :: Cipher
cipher_RC4_128_MD5 = Cipher
{ cipherID = 0x04
, cipherName = "RSA-rc4-128-md5"
, cipherBulk = bulk_rc4
, cipherHash = hash_md5
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
cipher_RC4_128_SHA1 :: Cipher
cipher_RC4_128_SHA1 = Cipher
{ cipherID = 0x05
, cipherName = "RSA-rc4-128-sha1"
, cipherBulk = bulk_rc4
, cipherHash = hash_sha1
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
cipher_AES128_SHA1 :: Cipher
cipher_AES128_SHA1 = Cipher
{ cipherID = 0x2f
, cipherName = "RSA-aes128-sha1"
, cipherBulk = bulk_aes128
, cipherHash = hash_sha1
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Just SSL3
}
cipher_AES256_SHA1 :: Cipher
cipher_AES256_SHA1 = Cipher
{ cipherID = 0x35
, cipherName = "RSA-aes256-sha1"
, cipherBulk = bulk_aes256
, cipherHash = hash_sha1
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Just SSL3
}
cipher_AES128_SHA256 :: Cipher
cipher_AES128_SHA256 = Cipher
{ cipherID = 0x3c
, cipherName = "RSA-aes128-sha256"
, cipherBulk = bulk_aes128
, cipherHash = hash_sha256
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Just TLS12
}
cipher_AES256_SHA256 :: Cipher
cipher_AES256_SHA256 = Cipher
{ cipherID = 0x3d
, cipherName = "RSA-aes256-sha256"
, cipherBulk = bulk_aes256
, cipherHash = hash_sha256
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Just TLS12
}