cryptostore-0.3.0.0: Serialization of cryptographic data types
LicenseBSD-style
MaintainerOlivier Chéron <olivier.cheron@gmail.com>
Stabilityexperimental
Portabilityunknown
Safe HaskellSafe-Inferred
LanguageHaskell2010

Crypto.Store.PKCS12

Description

Personal Information Exchange Syntax, aka PKCS #12.

Only password integrity mode and password privacy modes are supported.

Synopsis

Documentation

type IntegrityParams = (DigestAlgorithm, PBEParameter) Source #

Parameters used for password integrity mode.

readP12File :: FilePath -> IO (Either StoreError (OptAuthenticated PKCS12)) Source #

Read a PKCS #12 file from disk.

readP12FileFromMemory :: ByteString -> Either StoreError (OptAuthenticated PKCS12) Source #

Read a PKCS #12 file from a bytearray in BER format.

writeP12File :: FilePath -> IntegrityParams -> ProtectionPassword -> PKCS12 -> IO (Either StoreError ()) Source #

Write a PKCS #12 file to disk.

writeP12FileToMemory :: IntegrityParams -> ProtectionPassword -> PKCS12 -> Either StoreError ByteString Source #

Write a PKCS #12 file to a bytearray in DER format.

writeUnprotectedP12File :: FilePath -> PKCS12 -> IO () Source #

Write a PKCS #12 file without integrity protection to disk.

writeUnprotectedP12FileToMemory :: PKCS12 -> ByteString Source #

Write a PKCS #12 file without integrity protection to a bytearray in DER format.

PKCS #12 privacy

data PKCS12 Source #

PKCS #12 privacy wrapper, adding optional encryption to SafeContents. ASN.1 equivalent is AuthenticatedSafe.

The semigroup interface allows to combine multiple pieces encrypted separately but they should all derive from the same password to be readable by unPKCS12 and most other software.

Instances

Instances details
Semigroup PKCS12 Source # 
Instance details

Defined in Crypto.Store.PKCS12

Show PKCS12 Source # 
Instance details

Defined in Crypto.Store.PKCS12

Eq PKCS12 Source # 
Instance details

Defined in Crypto.Store.PKCS12

Methods

(==) :: PKCS12 -> PKCS12 -> Bool #

(/=) :: PKCS12 -> PKCS12 -> Bool #

unPKCS12 :: PKCS12 -> OptProtected [SafeContents] Source #

Read the contents of a PKCS #12. The same privacy password will be used for all content elements.

This convenience function returns a Protected value as soon as one element at least is encrypted. This does not mean all elements were actually protected in the input. If detailed view is required then function unPKCS12' is also available.

unPKCS12' :: PKCS12 -> [OptProtected SafeContents] Source #

Read the contents of a PKCS #12.

unencrypted :: SafeContents -> PKCS12 Source #

Build a PKCS #12 without encryption. Usage scenario is when private keys are already encrypted with PKCS8ShroudedKeyBag.

encrypted :: EncryptionScheme -> ProtectionPassword -> SafeContents -> Either StoreError PKCS12 Source #

Build a PKCS #12 encrypted with the specified scheme and password.

PKCS #12 contents and bags

newtype SafeContents Source #

Content objects stored in a PKCS #12.

Constructors

SafeContents 

Fields

Instances

Instances details
Show SafeContents Source # 
Instance details

Defined in Crypto.Store.PKCS12

Eq SafeContents Source # 
Instance details

Defined in Crypto.Store.PKCS12

type SafeBag = Bag SafeInfo Source #

Main bag type in a PKCS #12.

data Bag info Source #

Polymorphic PKCS #12 bag parameterized by the payload data type.

Constructors

Bag 

Fields

Instances

Instances details
Show info => Show (Bag info) Source # 
Instance details

Defined in Crypto.Store.PKCS12

Methods

showsPrec :: Int -> Bag info -> ShowS #

show :: Bag info -> String #

showList :: [Bag info] -> ShowS #

Eq info => Eq (Bag info) Source # 
Instance details

Defined in Crypto.Store.PKCS12

Methods

(==) :: Bag info -> Bag info -> Bool #

(/=) :: Bag info -> Bag info -> Bool #

data SafeInfo Source #

Main bag payload in PKCS #12 contents.

Constructors

KeyBag (FormattedKey PrivKey)

unencrypted private key

PKCS8ShroudedKeyBag PKCS5

encrypted private key

CertBag (Bag CertInfo)

certificate

CRLBag (Bag CRLInfo)

CRL

SecretBag [ASN1]

arbitrary secret

SafeContentsBag SafeContents

safe contents embeded recursively

Instances

Instances details
Show SafeInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

Eq SafeInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

newtype CertInfo Source #

Certificate bags. Only X.509 certificates are supported.

Instances

Instances details
Show CertInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

Eq CertInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

newtype CRLInfo Source #

CRL bags. Only X.509 CRLs are supported.

Constructors

CRLX509 SignedCRL 

Instances

Instances details
Show CRLInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

Eq CRLInfo Source # 
Instance details

Defined in Crypto.Store.PKCS12

Methods

(==) :: CRLInfo -> CRLInfo -> Bool #

(/=) :: CRLInfo -> CRLInfo -> Bool #

data Attribute Source #

An attribute extending the parent structure with arbitrary data.

Constructors

Attribute 

Fields

Instances

Instances details
Show Attribute Source # 
Instance details

Defined in Crypto.Store.CMS.Attribute

Eq Attribute Source # 
Instance details

Defined in Crypto.Store.CMS.Attribute

getSafeKeys :: SafeContents -> [OptProtected PrivKey] Source #

Return all private keys contained in the safe contents.

getAllSafeKeys :: [SafeContents] -> OptProtected [PrivKey] Source #

Return all private keys contained in the safe content list. All shrouded private keys must derive from the same password.

This convenience function returns a Protected value as soon as one key at least is encrypted. This does not mean all keys were actually protected in the input. If detailed view is required then function getSafeKeys is available.

getSafeX509Certs :: SafeContents -> [SignedCertificate] Source #

Return all X.509 certificates contained in the safe contents.

getAllSafeX509Certs :: [SafeContents] -> [SignedCertificate] Source #

Return all X.509 certificates contained in the safe content list.

getSafeX509CRLs :: SafeContents -> [SignedCRL] Source #

Return all X.509 CRLs contained in the safe contents.

getAllSafeX509CRLs :: [SafeContents] -> [SignedCRL] Source #

Return all X.509 CRLs contained in the safe content list.

PKCS #12 attributes

findAttribute :: OID -> [Attribute] -> Maybe [ASN1] Source #

Return the values for the first attribute with the specified type.

setAttribute :: OID -> [ASN1] -> [Attribute] -> [Attribute] Source #

Add or replace an attribute in a list of attributes.

filterAttributes :: (OID -> Bool) -> [Attribute] -> [Attribute] Source #

Filter a list of attributes based on a predicate applied to attribute type.

getFriendlyName :: [Attribute] -> Maybe String Source #

Return the value of the friendlyName attribute.

setFriendlyName :: String -> [Attribute] -> [Attribute] Source #

Add or replace the friendlyName attribute in a list of attributes.

getLocalKeyId :: [Attribute] -> Maybe ByteString Source #

Return the value of the localKeyId attribute.

setLocalKeyId :: ByteString -> [Attribute] -> [Attribute] Source #

Add or replace the localKeyId attribute in a list of attributes.

Credentials

fromCredential :: Maybe EncryptionScheme -> EncryptionScheme -> ProtectionPassword -> (CertificateChain, PrivKey) -> Either StoreError PKCS12 Source #

Build a PKCS12 value containing a private key and certificate chain. Distinct encryption is applied for both. Encrypting the certificate chain is optional.

Note: advice is to always generate fresh and independent EncryptionScheme values so that the salt is not reused twice in the encryption process.

fromNamedCredential :: String -> Maybe EncryptionScheme -> EncryptionScheme -> ProtectionPassword -> (CertificateChain, PrivKey) -> Either StoreError PKCS12 Source #

Build a PKCS12 value containing a private key and certificate chain identified with the specified friendly name. Distinct encryption is applied for private key and certificates. Encrypting the certificate chain is optional.

Note: advice is to always generate fresh and independent EncryptionScheme values so that the salt is not reused twice in the encryption process.

toCredential :: PKCS12 -> OptProtected (Maybe (CertificateChain, PrivKey)) Source #

Extract the private key and certificate chain from a PKCS12 value. A credential is returned when the structure contains exactly one private key and at least one X.509 certificate.

toNamedCredential :: String -> PKCS12 -> OptProtected (Maybe (CertificateChain, PrivKey)) Source #

Extract a private key and certificate chain with the specified friendly name from a PKCS12 value. A credential is returned when the structure contains exactly one private key and one X.509 certificate with the name.

Password-based protection

type Password = ByteString Source #

A password stored as a sequence of UTF-8 bytes.

Some key-derivation functions add restrictions to what characters are supported.

Beware: fromString truncates multi-byte characters. If the string may contain non-ASCII characters, prefer instead fromProtectionPassword . fromString.

data OptAuthenticated a Source #

Data type for objects that are possibly authenticated with a password.

Content is verified and retrieved by providing a Password value. When verification is successful, a value of type ProtectionPassword is also returned and this value can be fed to an inner decryption layer that needs the same password (usual case for PKCS #12).

Constructors

Unauthenticated a

Value is not authenticated

Authenticated (Password -> Either StoreError (ProtectionPassword, a))

Value is authenticated with a password

Instances

Instances details
Functor OptAuthenticated Source # 
Instance details

Defined in Crypto.Store.PKCS12

Methods

fmap :: (a -> b) -> OptAuthenticated a -> OptAuthenticated b #

(<$) :: a -> OptAuthenticated b -> OptAuthenticated a #

recoverAuthenticated :: Password -> OptAuthenticated a -> Either StoreError (ProtectionPassword, a) Source #

Try to recover an OptAuthenticated content using the specified password.

When successful, the content is returned, as well as the password converted to type ProtectionPassword. This password value can then be fed to the inner decryption layer when both passwords are known to be same (usual case for PKCS #12).

data ProtectionPassword Source #

A password stored as a sequence of UTF-8 bytes.

Some key-derivation functions add restrictions to what characters are supported.

The data type provides a special value emptyNotTerminated that is used as alternate representation of empty passwords on some systems and that produces encryption results different than an empty bytearray.

Conversion to/from a regular sequence of bytes is possible with functions toProtectionPassword and fromProtectionPassword.

Beware: the fromString implementation correctly handles multi-byte characters, so here is not equivalent to the ByteString counterpart.

emptyNotTerminated :: ProtectionPassword Source #

A value denoting an empty password, but having a special encoding when deriving a symmetric key on some systems, like the certificate export wizard on Windows.

This value is different from 'toProtectionPassword ""' and can be tried when decrypting content with a password known to be empty.

fromProtectionPassword :: ProtectionPassword -> ByteString Source #

Extract the UTF-8 bytes in a password value.

toProtectionPassword :: ByteString -> ProtectionPassword Source #

Build a password value from a sequence of UTF-8 bytes.

When the password is empty, the special value emptyNotTerminated may be tried as well.

data OptProtected a Source #

Data type for objects that are possibly protected with a password.

Constructors

Unprotected a

Value is unprotected

Protected (ProtectionPassword -> Either StoreError a)

Value is protected with a password

Instances

Instances details
Functor OptProtected Source # 
Instance details

Defined in Crypto.Store.PKCS8

Methods

fmap :: (a -> b) -> OptProtected a -> OptProtected b #

(<$) :: a -> OptProtected b -> OptProtected a #

recover :: ProtectionPassword -> OptProtected a -> Either StoreError a Source #

Try to recover an OptProtected content using the specified password.

recoverA :: Applicative f => f ProtectionPassword -> OptProtected a -> f (Either StoreError a) Source #

Try to recover an OptProtected content in an applicative context. The applicative password is used if necessary.

import qualified Data.ByteString as B
import           Crypto.Store.PKCS8

[encryptedKey] <- readKeyFile "privkey.pem"
let askForPassword = putStr "Please enter password: " >> B.getLine
result <- recoverA (toProtectionPassword <$> askForPassword) encryptedKey
case result of
    Left err  -> putStrLn $ "Unable to recover key: " ++ show err
    Right key -> print key