jose-0.3.38.0: src/Crypto/JOSE/JWK.hs
-- Copyright (C) 2013, 2014 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 OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-|
A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data
structure that represents a cryptographic key. This module also
defines a JSON Web Key Set (JWK Set) JSON data structure for
representing a set of JWKs.
-}
module Crypto.JOSE.JWK
(
JWK(JWK)
, jwkMaterial
, jwkUse
, jwkKeyOps
, jwkAlg
, jwkKid
, jwkX5u
, jwkX5c
, jwkX5t
, jwkX5tS256
, JWKSet(..)
, module Crypto.JOSE.JWA.JWK
) where
import Control.Applicative
import Data.Bifunctor
import Data.Maybe (catMaybes)
import Control.Lens hiding ((.=))
import Data.Aeson
import Crypto.JOSE.Classes
import qualified Crypto.JOSE.JWA.JWE.Alg as JWA.JWE
import Crypto.JOSE.JWA.JWK
import qualified Crypto.JOSE.JWA.JWS as JWA.JWS
import qualified Crypto.JOSE.TH
import qualified Crypto.JOSE.Types as Types
import qualified Crypto.JOSE.Types.Internal as Types
-- | JWK §3.3. "alg" (Algorithm) Parameter
--
data Alg = JWSAlg JWA.JWS.Alg | JWEAlg JWA.JWE.Alg
deriving (Eq, Show)
instance FromJSON Alg where
parseJSON v = (JWSAlg <$> parseJSON v) <|> (JWEAlg <$> parseJSON v)
instance ToJSON Alg where
toJSON (JWSAlg alg) = toJSON alg
toJSON (JWEAlg alg) = toJSON alg
-- | JWK §3.3. "key_ops" (Key Operations) Parameter
--
$(Crypto.JOSE.TH.deriveJOSEType "KeyOp"
[ "sign", "verify", "encrypt", "decrypt"
, "wrapKey", "unwrapKey", "deriveKey", "deriveBits"
])
-- | JWK §3.2. "use" (Public Key Use) Parameter
--
$(Crypto.JOSE.TH.deriveJOSEType "KeyUse" ["sig", "enc"])
-- | JWK §3. JSON Web Key (JWK) Format
--
data JWK = JWK
{
_jwkMaterial :: Crypto.JOSE.JWA.JWK.KeyMaterial
, _jwkUse :: Maybe KeyUse
, _jwkKeyOps :: Maybe [KeyOp]
, _jwkAlg :: Maybe Alg
, _jwkKid :: Maybe String
, _jwkX5u :: Maybe Types.URI
, _jwkX5c :: Maybe [Types.Base64X509]
, _jwkX5t :: Maybe Types.Base64SHA1
, _jwkX5tS256 :: Maybe Types.Base64SHA256
}
deriving (Eq, Show)
makeLenses ''JWK
instance FromJSON JWK where
parseJSON = withObject "JWK" $ \o -> JWK
<$> parseJSON (Object o)
<*> o .:? "use"
<*> o .:? "key_ops"
<*> o .:? "alg"
<*> o .:? "kid"
<*> o .:? "x5u"
<*> o .:? "x5c"
<*> o .:? "x5t"
<*> o .:? "x5t#S256"
instance ToJSON JWK where
toJSON (JWK {..}) = object $ catMaybes
[ fmap ("alg" .=) _jwkAlg
, fmap ("use" .=) _jwkUse
, fmap ("key_ops" .=) _jwkKeyOps
, fmap ("kid" .=) _jwkKid
, fmap ("x5u" .=) _jwkX5u
, fmap ("x5c" .=) _jwkX5c
, fmap ("x5t" .=) _jwkX5t
, fmap ("x5t#S256" .=) _jwkX5tS256
]
++ Types.objectPairs (toJSON _jwkMaterial)
instance Key JWK where
type KeyGenParam JWK = Crypto.JOSE.JWA.JWK.KeyMaterialGenParam
type KeyContent JWK = Crypto.JOSE.JWA.JWK.KeyMaterial
gen p = first fromKeyContent . gen p
fromKeyContent k = JWK k z z z z z z z z where z = Nothing
public = jwkMaterial public
sign h k = sign h $ k ^. jwkMaterial
verify h k = verify h $ k ^. jwkMaterial
-- | JWK §4. JSON Web Key Set (JWK Set) Format
--
newtype JWKSet = JWKSet [JWK] deriving (Eq, Show)
instance FromJSON JWKSet where
parseJSON = withObject "JWKSet" (\o -> JWKSet <$> o .: "keys")