Giter Club home page Giter Club logo

saltine's Introduction

Saltine 0.2.1.0 Hackage version

A Haskell binding for @jedisct1's portable binding for djb's NaCl. This is an early release. Please try it out, but don't just yet stake your life or job on it.

It is imperative you call sodiumInit before using any other function.

import           Crypto.Saltine
import           Crypto.Saltine.Core.SecretBox
import qualified Data.ByteString.Char8 as BSC8

main = do
  sodiumInit
  k <- newKey
  n <- newNonce
  let ciphertext = secretbox k n (BSC8.pack "foobar")
  print $ secretboxOpen k n ciphertext

-- Just "foobar"

In The Security Impact of a New Cryptographic Library Bernstein, Lange, and Schwabe argue that high-level cryptographic libraries eliminate whole spaces of cryptographic disasters which are nigh inevitable whenever programmers use low-level crypto primitives.

Crypto is complicated, so pre-rolled solutions are important prevention mechanisms.

NaCl is Bernstein, Lange, and Schwabe's solution: a high-level, performant cryptography library with a no-fuss interface. Saltine is a Haskell binding to NaCl (via libsodium) which hopes to provide even more simplicity and safety to the usage of cryptography.

Note that it's still possible to shoot yourself in the foot pretty easily using Saltine. Nonces must always be unique which must be managed by the library user. Crypto.Saltine.Core.Stream produces messages which can beundetectably tampered with in-flight. Keys are insecurely read from disk—they may be copied and then paged back to disk.

When uncertain, use Crypto.Saltine.Core.SecretBox and Crypto.Saltine.Core.Box. If you can think of ways to use Haskell's type system to enforce security invariants, please suggest them.

To use it on Windows systems, download a prebuild libsodium-*-stable-mingw.tar.gz file and copy the files in libsodium-win64 into the equivalent places in C:\Program Files\Haskell Platform\*\mingw. Then just add saltine to your cabal file and watch it go.

Tested with libsodium-1.0.18.

Inspired by @thoughtpolice's salt library. salt also binds to NaCl, but uses a Haskell managed version of djb's code instead of libsodium.

saltine's People

Contributors

donatello avatar hce avatar joachifm avatar linearray avatar nicolast avatar ns476 avatar qybta avatar tel avatar timds avatar tmcl avatar tommd avatar wyager avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saltine's Issues

Hashable instances for key types

Would be nice to be able to include public keys (and data structures containing them) in HashSets.

Or at least have an Internal module exporting the *Key constructors so that can be done by the user.

Expose `randomVector`

Would a patch exposing the module Crypto.Saltine.Core.Util which re-exports randomVector be accepted? I could always use entropy but reducing dependencies would be great.

Upload haddocks to Hackage

Hackage cannot build the package, so manually uploading the haddocks is necessary.
Not essential, I suppose, but nice nonetheless and lowers the barrier to entry, IMO.

Add bindings for key derivation functions

libsodium provides an interface to

(a) Derive keys using a high entropy master key, a sequential index and a context (8 byte string);
(b) Derive a key from a password.

I don't see bindings for them so far.

Would you accept a pull request for this?

Show instances

I'm building a simple session cache out of public keys and nonces, and it would be extremely useful if there were hashable instances for all the ByteString-convertable types, like Nonce PublicKey etc. I've just been building my own, out of newtypes and conversions, but I think these instances speak for themselves for how useful they could be. I may just implement it myself and submit a PR if that's okay :)

Expose _aead prims?

I have a use for the sodium aead functions. Would a pull request that adds a new module for these operations be accepted?

Built-in noncing strategies

One of the biggest weaknesses of using NaCl is that nonces must all be unique and it's up to the end user to ensure that. newNonce is sufficient for all of default NaCl, but it requires IO. IsNonce can help in pure settings, but you have to remember to always call nudge. If there was a Noncey monad it'd be easy enough to statically ensure this behavior locally. There are times that two communicating parties would want to collaborate on nonce incrementing, though, so those strategies would have to be possible: Endo Nonce?

Provide helper functions to treat nonces as integers

Sometimes you want to use an integer as a nonce. For example, Alice might send messages to Bob using the numbers 1,3,5, ... as nonces and similarly Bob might use 2,4,6,... for the messages he sends to Alice. Another common case is to select a random nonce to encrypt the first message and then keep incrementing it for subsequent messages (sort of like a counter mode). I propose to include 2 helper functions to saltine to help with these cases:

succNonce :: Nonce -> Nonce
nonceFromInt :: Integral a => a -> Nonce

Care must be taken to make sure that those functions are implemented in an endianness independent fashion.

Here are naive implementation of the above functions, representing integers in little endian form:

succNonce :: Nonce -> Nonce
succNonce n = n'
  where
    Just n' = SC.decode $ B.pack $ succList $ B.unpack $ SC.encode n

succList :: (Bounded a, Enum a, Eq a) => [a] -> [a]
succList (x : xs)
    | x == maxBound = minBound : succList xs
    | otherwise = succ x : xs
succList [] = []

and

nonceFromInt :: Integral a => a -> Nonce
nonceFromInt x = n
  where
    Just n = SC.decode $ B.pack $ take nonceBytes $ littleEndianBytes x
    -- this is vert ugly, a #const must be used here
    nonceBytes = B.length $ SC.encode $ unsafeDupablePerformIO newNonce

littleEndianBytes :: Integral a => a -> [Word8]
littleEndianBytes x = fromIntegral r : littleEndianBytes q
  where
    (q, r) = x `quotRem` 256

where SC is Crypto.Saltine.Class and B is Data.ByteString.

Upload new package with relaxed base version restriction

 ~/ % cabal install saltine --reinstall
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: saltine-0.0.0.3 (user goal)
next goal: base (dependency of saltine-0.0.0.3)
rejecting: base-4.8.0.0/installed-1b6... (conflict: saltine => base>=4.5 &&
<4.8)
rejecting: base-4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1, 4.6.0.0, 4.5.1.0,
4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0,
4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (global constraint requires installed
instance)
Dependency tree exhaustively searched.

The current HEAD has base < 5 set already.

Auto-wipe keys

It'd be nice if the memory used to store (private, symmetric) keys was wiped automatically when the keys are gc'ed.

What do you think of the idea/would you accept a patch for that?

Better access for SecretKey/PublicKey/CombinedKey/Key/Nonce

Right now these are totally opaque boxes, which is a problem. Ideally it'd be nice to have a lens-like IsByteString class to project into them. Unfortunately, that can't quite work because IsByteString needs Iso's. There's already a Crypto.Saltine.Class module containing IsEncoding which provides Prism' access to these guys.

This'll also lead to nice Show instances for these guys.

Benchmarking

A benchmarking suite ought to exist and be used to quantify any improvements.

Stronger types for detached signature interfaces

In my code I have:

-- | A NaCl signature.
newtype Signature = Signature -- ctor not exported from public interface
  { -- | Extract the bytes of a 'Signature'. Guaranteed to be the
    -- right length.
    unSignature :: ByteString
  }

-- | Build a 'Signature'.
--
-- Can fail if the passed in bytes are not the right length.
makeSignature :: ByteString -> Maybe Signature
makeSignature b
  | BS.length b == NaClSizes.sign = Just (Signature b)
  | otherwise = Nothing

Would be nice to have something like this upstream and the relevant functions take a Signature instead of a Bytestring

Add binding to crypto_sign_seed_keypair

There is already a binding (newKeypair) for crypto_sign_keypair which generates a keypair from random bytes; however, there is no binding for crypto_sign_seed_keypair which generates a keypair from a seed the caller provides.

Nonce tests

There should be some test of the various Nonce implementations---mostly that nudge has a sufficiently long orbit?

Sealed boxes

Hi,

I was wondering if there was any work done on adding support for sealed boxes, essentially boxes with encryption but not authentication, which were added in libsodium 1.0.3

If not, I'm going to give it a shot. Just wanted to make sure it's not already lying around somewhere.

Add "unsafe" API for complex features

It seems that there are a number of features in Libsodium that can be useful in some situations, while posing additional risks to the unwary user, eg. keypair derivation from a known seed: #18

Additionally, the existing API in Saltine already includes some functions that should be regarded as dangerous (the Crypto.Saltine.Core.Stream undetectable malleability issue, and Crypto.Saltine.Core.ScalarMult which is really an advanced feature and public key derivation/key exchange should rather be exported as specific APIs using the functions from Libsodium so people don't feel the need to build their own from the primitives).

I've been working on my own fork on exposing all interesting parts of Libsodium in Crypto.Saltine.Unsafe.* modules and only leaving the safest and easiest functionality in Crypto.Saltine.Core.*, one addition being a high-level key exchange API which exports functions for the client and server to operate on an opaque SessionKeys type, using the correct key for sending+receiving under the hood. It's not directly pull-request-compatible due to breaking API changes but I think this would be a good approach to take towards version 1.0.0.0

0.2.0.0 failing on stackage

We are seeing:

Configuring saltine-0.2.0.0...
Cabal-simple_mPHDZzAJ_3.2.1.0_ghc-8.10.4: The pkg-config package 'libsodium'
version ==1.0.18 || >1.0.18 is required but the version installed on the
system is version 1.0.16

For now we have reverted to 0.1.1.1

MacOS: Tests fail

MacOS 10.13.4, Xcode-9.3, GHC-8.2.2, current stack and cabal.

$ cabal test --show-details=always
Preprocessing library for saltine-0.1.0.1..
Building library for saltine-0.1.0.1..
Preprocessing test suite 'tests' for saltine-0.1.0.1..
Building test suite 'tests' for saltine-0.1.0.1..
Running 1 test suites...
Test suite tests: RUNNING...
Test suite tests: FAIL
Test suite logged to: dist/test/saltine-0.1.0.1-tests.log
0 of 1 test suites (0 of 1 test cases) passed.
$ cat dist/test/saltine-0.1.0.1.log
PackageLog {package = PackageIdentifier {pkgName = PackageName "saltine", pkgVersion = mkVersion [0,1,0,1]}, compiler = CompilerId GHC (mkVersion [8,2,2]), platform = Platform X86_64 OSX, testSuites = [TestSuiteLog {testSuiteName = UnqualComponentName "tests", testLogs = TestLog {testName = "tests", testOptionsReturned = [], testResult = Fail "exit code: -11"}, logFile = "dist/test/saltine-0.1.0.1-tests.log"}]}
$ cat dist/test/saltine-0.1.0.1-tests.log
Test suite tests: RUNNING...
Test suite tests: FAIL
Test suite logged to: dist/test/saltine-0.1.0.1-tests.log
$

Here's the complete console output:
saltine-test-out.txt

Is there any way to get some meaningful error message from the tests? The log as-is is practically useless - it does not tell what tests ran, what tests failed, and more importantly - failed how/on what...

Help is appreciated.

"unknown symbol pthread_mutex_lock" in windows

Hello, I'm trying to invoke some saltine functions at compile time with TemplateHaskell. I've built saltine-0.0.0.4 independently and run stack test, and everything works fine, I just need to build and test with a little library path lookup awkwardness:

# builds without a hitch
stack build --extra-include-dirs ~/dev/libsodium-win64/include --extra-lib-dirs ~/dev/libsodium-win64/lib

# testing works, but I need to copy a DLL for linking, because Windows
cp ~/dev/libsodium-win64/bin/libsodium-18.dll ./
stack test --extra-include-dirs ~/dev/libsodium-win64/include --extra-lib-dirs ~/dev/libsodium-win64/lib

All the tests pass, which gives me a lot of confidence. But for some reason, I'm getting a strange error when trying to run Crypto.Saltine.Core.Box.newKeypair with a -XTemplateHaskell splice:

The strange thing; GHC says it can't find sodium-0.0.0.4, yet in my stack.yaml I have my local build listed:

# ...
packages:
  - location: '../saltine-0.0.0.4'
    extra-dep: true
# ...

Wouldn't the build fail before getting to my project if it couldn't find the sodium-0.0.0.4 dependency? It's a strange error there, definitely, but the detrimental one for me is the "unknown symbol pthread_mutex_lock" error coming from libsodium.a.

Is this a common error / debug symbol? I'm no C++ dev or anything, but it sounds like this prebuilt libsodium.a includes POSIX symbols or something, when it's intended to build only for Windows. I'm not sure what's going on here.

@jedisct1 Do you happen to know what might be wrong here? Shouldn't the Windows builds exclude POSIX debug symbols?

Please allow newer `profunctors`

I have succesfully built this using ghc-8.10.3 and profunctors-5.6.1.

If you are able to make this change and release a new version, it will allow us to better package this project in gentoo.

Unable to construct own Nonce

I'm trying to implement a NaCl based protocol. It requires to use nonces that are generated by concatenating a nonce-prefix and a counter. For example:

noncePrefix = "abcdefghijklmnop"
counter = 1
nonce = generateNonce noncePrefix counter # => "abcdefghijklmnop00000001"

My problem is that I'm unable to use my own nonces with the secretbox function, because I can't create the Nonce type. Internally Nonce is implemented as a newtype for ByteString, but the constructor can only be used inside the Crypto.Saltine.Core.SecretBox package.

If you agree that this is a valid use case, I'd like to send a pull-request that exposes the Nonce type constructor for the Nonce types in Crypto.Saltine.Core.SecretBox, Crypto.Saltine.Core.Box and Crypto.Saltine.Core.Stream.

Support ChaCha20-Poly2105 IETF variant

Libsodium now has support for this AEAD scheme specified originally in RFC7539 (superseded by 8439 which is compatible AFAIK), which is now also implemented in Java and used in TLS 1.3.

Available in libsodium for three years: jedisct1/libsodium@de451c2

It would be nice if there were bindings for it.

Streaming, ByteArray or conduit interface for large payloads

Currently only strict ByteStrings are supported. For large payloads, a conduit interface would be awesome. Alternatives include lazy ByteStrings (which are somewhat deprecated afaict) or the more generic ByteArray(Access) interface that supports various sources of bytes.

Lens interface

Sort of wishful thinking, but ciphertext ^. plaintext is nice.

Thread safety for random functions.

The random generation functions are not threadsafe, so it's unclear what their behavior will be in concurrent settings.

  • randombytes_random
  • randombytes_uniform
  • randombytes_buf
  • randombytes_close
  • crypto_sign_keypair, and
  • crypto_box_keypair

Two different PublicKey types?

Hi!
More a question than a bug report: Is there a reason to have two different public (and secret) key types for box and sign? I think it would be ok, to use the same keypairs for both types for operations.
Am I wrong? Currently I convert between both via isEncoding, but that feels a little bit poor.
Götz

Fatal malloc error when AEAD ciphertext is invalid

: ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /Users/williamyager/.ghci
> import Crypto.Saltine.Core.AEAD
> (\k n -> aeadOpen k n "a" "b") <$> newKey <*> newNonce
*** Exception: malloc: resource exhausted (out of memory)

Invalid AAD seems fine. Invalid ciphertext causes this error.

Looks like this happens when the ciphertext is too short.

My guess: There's a subtraction on ssize_ts/Words that is unchecked and underflows if the provided "ciphertext" is less than the padding length.

Understanding ScalarMult

ScalarMult appears to be a primitive for performing hashed Diffie-Hellman exchanges. That's a really low-level primitive, though. Is it possible to wrap it in a nicer interface?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.