packages feed

jose-0.13: test/AESKW.hs

-- Copyright (C) 2016  Fraser Tweedale
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}

module AESKW
  ( aeskwProperties
  ) where

import qualified Data.ByteString as B
import Crypto.Cipher.AES
import Crypto.Cipher.Types
import Crypto.Error

import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Test.Tasty
import Test.Tasty.Hedgehog

import Crypto.JOSE.AESKW


aeskwProperties :: TestTree
aeskwProperties = testGroup "AESKW"
  [ let n = "AESKW round-trip" in testPropertyNamed n n prop_roundTrip
  ]

prop_roundTrip :: Property
prop_roundTrip = property $ do
  cekLen <- forAll $ (* 8) . (+ 2) <$> Gen.integral (Range.linear 0 16)
  cek <- forAll $ Gen.bytes (Range.singleton cekLen)
  kekLen <- forAll $ Gen.element [16, 24, 32]
  kek <- forAll $ Gen.bytes (Range.singleton kekLen)
  let
    go cipher' = case cipher' of
      CryptoFailed _ -> do
        annotate "cipherInit failed"
        failure
      CryptoPassed cipher -> do
        let
          c = aesKeyWrap cipher cek :: B.ByteString
          cek' = aesKeyUnwrap cipher c
        B.length c === cekLen + 8
        cek' === Just cek
  case kekLen of
    16 -> go (cipherInit kek :: CryptoFailable AES128)
    24 -> go (cipherInit kek :: CryptoFailable AES192)
    32 -> go (cipherInit kek :: CryptoFailable AES256)
    _  -> annotate "the impossible happened" *> failure   -- can't happen