Closed burke closed 9 years ago
Implements EJSON v1.0 RFC except with nacl/box instead of PKCS7
:heart:
I am a huge fan of NaCl, and quite wary of the PKCS standards.
djb :100:
I added manpages which are installed with the debian package and vendored with the rubygem (unfortunately rubygems can't install manpages globally). ejson help
, ejson help encrypt
, etc., will now launch man
for the relevant manpage.
What happens if you try to encrypt:
"_starts_with_an_underscore": {
"no_leading_underscore": "123123123123123123123"
}
I'm assuming it does the simple thing, and encrypts the value anyways, I'm just wondering if that's the nicest behaviour or if it should at least be documented?
@eapache it's not in the manpage, but it is in README.md: https://github.com/Shopify/ejson/tree/go-impl#format (see point 6). I'll add it to ejson.5.
(I want to err on the side of encrypting too much rather than too little, so this is the behaviour I want, though I'm open to argument on that point)
:+1: to explanation and documenting it
Also fun: http://shopify.github.io/ejson/
@burke any plans to add schemas to the Go version?
Yeah, but I plan to do that in a separate codebase, probably just a gem that plugs in to rails. There's no reason that bit has to clutter the ejson codebase.
log.Fatal
instead of just returning the error and letting the caller do what it wants?..
?ioutil.WriteFile
, that's all.err.Error()
into the new error string. Will do.Actually, I think it's unreasonable to prevent traversal here: The only input value is the keydir, which is allowed to be anywhere on the system.
I made the other two changes.
The only input value is the keydir, which is allowed to be anywhere on the system.
The other input is the key; is there an escalation where a user can generate a fake public key to escape the key-dir?
I don't think so; if they do, they've found a bug in printf
's %x
formatter, not so much in ejson
. I don't personally feel we need to be quite that defensive. I like the train of thought though, that hadn't occurred to me.
sarama
and using a package-global Logger
that the importing package can set up appropriately?)cmd/ejson
package.Also, I really like that the current system preserves the input formatting. Explicit ordering would interfere with semantic grouping, might put _public_key
in a weird place in the file, and would just generally violate user expectations.
I'll try to make the json stuff better, but I don't think there's a better option than the scanner.
\A
and \z
to ^
and $
- json can't contain embedded newlines I don't think but just as best-practice:
-separated groups and we know all three are base64-encoded; extra strictness is probably a good thing, unless it comes at the cost of too much readabilityLoad
simpler if it can just decode right into the struct, and the boxedMessage
is already a pointer./dev/random
instead of whatever is provided by rand.Reader
from crypto/rand
?main.go
, but whatever. Not exactly a big deal :P--help
EncryptFileInPlace
especially since DecryptFile
does not overwrite in place, otherwise the expectation will be that they reverse each otherLots of minor comments, but on the whole I really like this, :+1:
\A
\z
&
them when I pass them)crypto.rand
uses /dev/urandom
(really, getrandom
without GRND_RANDOM
). I don't love the idea of using a PRNG for key generation, especially when reading from /dev/random
is so trivial. Thoughts?os.Exit(1)
after manpage: It's because that will only ever happen if the syscall.Exec
fails. (syscall.Exec
is a true exec
). So the Exit(1)
here is appropriate, as it indicates the manpage wasn't found or something.EncryptFileInPlace
especially when reading from /dev/random is so trivial. Thoughts?
It is, I think, the only thing keeping the library part here from being cross-platform (making the whole thing cross-platform would also require ripping out the man-page bits). Security-specific discussion has been taken offline.
I replied to your email, but TL;DR: It's not the hugest of deals but I figured I'd do it right.
I have no real desire to support this on Windows, so I don't feel too bad about reading from /dev/*
directly in that regard.
I'll take a look at this, this is cool.
Back to crypto/rand
: https://github.com/Shopify/ejson/commit/629edb0e177a5b230f5b6357dcfb1e8ea3177139
To summarize our discussion offline, /dev/urandom
is fine but Go's PRNG is not. Go will use /dev/urandom
on linux, and probably only falls back to the bad implenetation on Windows and maybe plan9.
First of all, it's a nicely commented and structured project. Good job!
Few comments reading through it:
writeFile
from a stat, open(2)
only uses permissions if O_CREAT
is set iirc. -o
flag, otherwise someone redirecting output to a file might run into nasty bugs as they try to parse an error as JSON. With this, I'm not sure I'm seeing how schemas could be built on top of it in a reasonable way where everything isn't encrypted?
ioutil.WriteFile
requires a mode: http://golang.org/pkg/io/ioutil/#WriteFile-o
flag."tokens": ["token1", "token2"]
for rotation or load-balancing or whatever.{,_}description
is present, so for each metadata attribute you could choose whether or not to encrypt it. I'm going to write the validator on the plane tomorrow I think.Also, it's probably worth pointing out that gojson
is actually the builtin encoding/json
library, only with some lowercase letters made uppercase to expose the scanner API.
Also, it's probably worth pointing out that
gojson
is actually the builtinencoding/json
library
...from some unspecified point in the past. Better than something hand-rolled I guess, but still a bit icky. Alas.
...from some unspecified point in the past. Better than something hand-rolled I guess, but still a bit icky. Alas.
Agree on all counts.
I'd PR this, but it has no code in common with the previous ruby implementation, so it wouldn't provide a whole lot of value.
Instead, see https://github.com/Shopify/ejson
Highlights:
Makefile
generates rubygem and debian package/opt/ejson/keys
directory contains files named with full public key, containing private key.ejson decrypt
looks up key referenced by ejson file in/opt/ejson/keys
I'll keep poking at this over the next couple of days, but it's basically ready for feedback. The code is pretty well compartmentalized and documented; I don't think it'll be very hard to grok what's going on. Start with
README.md
, thenejson.go
andcmd/ejson/*.go
.Review/cc any combination of: @Shopify/stack, @Shopify/secops. It can easily wait until BFCM if you're busy.