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.AES as AES
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
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
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
}