initial commit

This commit is contained in:
Eric Chiang
2016-07-25 13:00:28 -07:00
commit cab271f304
1438 changed files with 335968 additions and 0 deletions

122
vendor/github.com/gtank/cryptopasta/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,122 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

121
vendor/github.com/gtank/cryptopasta/README generated vendored Normal file
View File

@@ -0,0 +1,121 @@
TL;DR- Copy & paste your crypto code from here instead of Stack Overflow.
This library demonstrates a suite of basic cryptography from the Go standard
library. To the extent possible, it tries to hide complexity and help you avoid
common mistakes. The recommendations were chosen as a compromise between
cryptographic qualities, the Go standard lib, and my existing use cases.
Some particular design choices I've made:
1. SHA-512/256 has been chosen as the default hash for the examples. It's
faster on 64-bit machines and immune to length extension. If it doesn't work
in your case, replace instances of it with ordinary SHA-256.
2. The specific ECDSA parameters were chosen to be compatible with RFC7518[1]
while using the best implementation of ECDSA available. Go's P-256 is
constant-time (which prevents certain types of attacks) while its P-384 and
P-521 are not.
3. Key parameters are arrays rather than slices so the compiler can help you
avoid mixing up the arguments. The signing and marshaling functions use the
crypto/ecdsa key types directly for the same reason.
4. Public/private keypairs for signing are marshaled into and out of PEM
format, making them relatively portable to other crypto software you're
likely to use (openssl, cfssl, etc).
5. Key generation functions will panic if they can't read enough random bytes
to generate the key. Key generation is critical, and if crypto/rand fails at
that stage then you should stop doing cryptography on that machine immediately.
6. The license is a CC0 public domain dedication, with the intent that you can
just copy bits of this directly into your code and never be required to
acknowledge my copyright, provide source code, or do anything else commonly
associated with open licenses.
The specific recommendations are:
Encryption - 256-bit AES-GCM with random 96-bit nonces
Using AES-GCM (instead of AES-CBC, AES-CFB, or AES-CTR, all of which Go also
offers) provides authentication in addition to confidentiality. This means that
the content of your data is hidden and that any modification of the encrypted
data will result in a failure to decrypt. This rules out entire classes of
possible attacks. Randomized nonces remove the choices around nonce generation
and management, which are another common source of error in crypto
implementations.
The interfaces in this library allow only the use of 256-bit keys.
Hashing - HMAC-SHA512/256
Using hash functions directly is fraught with various perils it's common for
developers to accidentally write code that is subject to easy collision or
length extension attacks. HMAC is a function built on top of hashes and it
doesn't have those problems. Using SHA-512/256 as the underlying hash function
means the process will be faster on 64-bit machines, but the output will be the
same length as the more familiar SHA-256.
This interface encourages you to scope your hashes with an English-language
string (a "tag") that describes the purpose of the hash. Tagged hashes are a
common "security hygiene" measure to ensure that hashing the same data for
different purposes will produce different outputs.
Password hashing - bcrypt with work factor 14
Use this to store users' passwords and check them for login (e.g. in a web
backend). While they both have "hashing" in the name, password hashing is an
entirely different situation from ordinary hashing and requires its own
specialized algorithm. bcrypt is a hash function designed for password storage.
It can be made selectively slower (based on a "work factor") to increase the
difficulty of brute-force password cracking attempts.
As of 2016, a work factor of 14 should be well on the side of future-proofing
over performance. If it turns out to be too slow for your needs, you can try
using 13 or even 12. You should not go below work factor 12.
Symmetric Signatures / Message Authentication - HMAC-SHA512/256
When two parties share a secret key, they can use message authentication to
make sure that a piece of data hasn't been altered. You can think of it as a
"symmetric signature" - it proves both that the data is unchanged and that
someone who knows the shared secret key generated it. Anyone who does not know
the secret key can neither validate the data nor make valid alterations.
This comes up most often in the context of web stuff, such as:
1. Authenticating requests to your API. The most widely known example is
probably the Amazon AWS API, which requires you to sign requests with
HMAC-SHA256. In this type of use, the "secret key" is a token that the API
provider issues to authorized API users.
2. Validating authenticated tokens (cookies, JWTs, etc) that are issued by a
service but are stored by a user. In this case, the service wants to ensure
that a user doesn't modify the data contained in the token.
As with encryption, you should always use a 256-bit random key to
authenticate messages.
Asymmetric Signatures - ECDSA on P-256 with SHA-256 message digests
These are the classic public/private keypair signatures that you probably think
of when you hear the word "signature". The holder of a private key can sign
data that anyone who has the corresponding public key can verify.
Go takes very good care of us here. In particular, the Go implementation of
P-256 is constant time to protect against side-channel attacks, and the Go
implementation of ECDSA generates safe nonces to protect against the type of
repeated-nonce attack that broke the PS3.
In terms of JWTs, this algorithm is called "ES256". The functions
"EncodeSignatureJWT" and "DecodeSignatureJWT" will convert the basic signature
format to and from the encoding specified by RFC7515[2]
[1] https://tools.ietf.org/html/rfc7518#section-3.1
[2] https://tools.ietf.org/html/rfc7515#appendix-A.3

75
vendor/github.com/gtank/cryptopasta/encrypt.go generated vendored Normal file
View File

@@ -0,0 +1,75 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides symmetric authenticated encryption using 256-bit AES-GCM with a random nonce.
package cryptopasta
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
)
// NewEncryptionKey generates a random 256-bit key for Encrypt() and
// Decrypt(). It panics if the source of randomness fails.
func NewEncryptionKey() *[32]byte {
key := [32]byte{}
_, err := io.ReadFull(rand.Reader, key[:])
if err != nil {
panic(err)
}
return &key
}
// Encrypt encrypts data using 256-bit AES-GCM. This both hides the content of
// the data and provides a check that it hasn't been altered. Output takes the
// form nonce|ciphertext|tag where '|' indicates concatenation.
func Encrypt(plaintext []byte, key *[32]byte) (ciphertext []byte, err error) {
block, err := aes.NewCipher(key[:])
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := make([]byte, gcm.NonceSize())
_, err = io.ReadFull(rand.Reader, nonce)
if err != nil {
return nil, err
}
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt decrypts data using 256-bit AES-GCM. This both hides the content of
// the data and provides a check that it hasn't been altered. Expects input
// form nonce|ciphertext|tag where '|' indicates concatenation.
func Decrypt(ciphertext []byte, key *[32]byte) (plaintext []byte, err error) {
block, err := aes.NewCipher(key[:])
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
return gcm.Open(nil,
ciphertext[:gcm.NonceSize()],
ciphertext[gcm.NonceSize():],
nil,
)
}

104
vendor/github.com/gtank/cryptopasta/encrypt_test.go generated vendored Normal file
View File

@@ -0,0 +1,104 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
package cryptopasta
import (
"bytes"
"crypto/rand"
"io"
"io/ioutil"
"testing"
"golang.org/x/crypto/nacl/secretbox"
)
func TestEncryptDecryptGCM(t *testing.T) {
randomKey := &[32]byte{}
_, err := io.ReadFull(rand.Reader, randomKey[:])
if err != nil {
t.Fatal(err)
}
gcmTests := []struct {
plaintext []byte
key *[32]byte
}{
{
plaintext: []byte("Hello, world!"),
key: randomKey,
},
}
for _, tt := range gcmTests {
ciphertext, err := Encrypt(tt.plaintext, tt.key)
if err != nil {
t.Fatal(err)
}
plaintext, err := Decrypt(ciphertext, tt.key)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(plaintext, tt.plaintext) {
t.Errorf("plaintexts don't match")
}
ciphertext[0] ^= 0xff
plaintext, err = Decrypt(ciphertext, tt.key)
if err == nil {
t.Errorf("gcmOpen should not have worked, but did")
}
}
}
func BenchmarkAESGCM(b *testing.B) {
randomKey := &[32]byte{}
_, err := io.ReadFull(rand.Reader, randomKey[:])
if err != nil {
b.Fatal(err)
}
data, err := ioutil.ReadFile("testdata/big")
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
Encrypt(data, randomKey)
}
}
func BenchmarkSecretbox(b *testing.B) {
randomKey := &[32]byte{}
_, err := io.ReadFull(rand.Reader, randomKey[:])
if err != nil {
b.Fatal(err)
}
nonce := &[24]byte{}
_, err = io.ReadFull(rand.Reader, nonce[:])
if err != nil {
b.Fatal(err)
}
data, err := ioutil.ReadFile("testdata/big")
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
secretbox.Seal(nil, data, nonce, randomKey)
}
}

49
vendor/github.com/gtank/cryptopasta/hash.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides a recommended hashing algorithm.
//
// The hash function is HMAC-SHA512/256 where SHA512/256 is as described in
// FIPS 180-4. This construction avoids length-extension attacks while
// maintaining a widely compatible digest size with better performance on
// 64-bit systems.
//
// Password hashing uses bcrypt with a work factor of 14.
package cryptopasta
import (
"crypto/hmac"
"crypto/sha512"
"golang.org/x/crypto/bcrypt"
)
// Hash generates a hash of data using HMAC-SHA-512/256. The tag is intended to
// be a natural-language string describing the purpose of the hash, such as
// "hash file for lookup key" or "master secret to client secret". It serves
// as an HMAC "key" and ensures that different purposes will have different
// hash output. This function is NOT suitable for hashing passwords.
func Hash(tag string, data []byte) []byte {
h := hmac.New(sha512.New512_256, []byte(tag))
h.Write(data)
return h.Sum(nil)
}
// HashPassword generates a bcrypt hash of the password using work factor 14.
func HashPassword(password []byte) ([]byte, error) {
return bcrypt.GenerateFromPassword(password, 14)
}
// CheckPassword securely compares a bcrypt hashed password with its possible
// plaintext equivalent. Returns nil on success, or an error on failure.
func CheckPasswordHash(hash, password []byte) error {
return bcrypt.CompareHashAndPassword(hash, password)
}

91
vendor/github.com/gtank/cryptopasta/hash_test.go generated vendored Normal file
View File

@@ -0,0 +1,91 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
package cryptopasta
import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"testing"
)
func TestPasswordHashing(t *testing.T) {
bcryptTests := []struct {
plaintext []byte
hash []byte
}{
{
plaintext: []byte("password"),
hash: []byte("$2a$14$uALAQb/Lwl59oHVbuUa5m.xEFmQBc9ME/IiSgJK/VHtNJJXASCDoS"),
},
}
for _, tt := range bcryptTests {
hashed, err := HashPassword(tt.plaintext)
if err != nil {
t.Error(err)
}
if err = CheckPasswordHash(hashed, tt.plaintext); err != nil {
t.Error(err)
}
}
}
// Benchmarks SHA256 on 16K of random data.
func BenchmarkSHA256(b *testing.B) {
data, err := ioutil.ReadFile("testdata/random")
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
_ = sha256.Sum256(data)
}
}
// Benchmarks SHA512/256 on 16K of random data.
func BenchmarkSHA512_256(b *testing.B) {
data, err := ioutil.ReadFile("testdata/random")
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
_ = sha512.Sum512_256(data)
}
}
func BenchmarkBcrypt(b *testing.B) {
for i := 0; i < b.N; i++ {
_, err := HashPassword([]byte("thisisareallybadpassword"))
if err != nil {
b.Error(err)
break
}
}
}
func ExampleHash() {
tag := "hashing file for lookup key"
contents, err := ioutil.ReadFile("testdata/random")
if err != nil {
fmt.Printf("could not read file: %v\n", err)
os.Exit(1)
}
digest := Hash(tag, contents)
fmt.Println(hex.EncodeToString(digest))
// Output: 9f4c795d8ae5c207f19184ccebee6a606c1fdfe509c793614066d613580f03e1
}

113
vendor/github.com/gtank/cryptopasta/marshal.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides encoding and decoding routines for various cryptographic structures.
package cryptopasta
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
)
// DecodePublicKey decodes a PEM-encoded ECDSA public key.
func DecodePublicKey(encodedKey []byte) (*ecdsa.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
ecdsaPub, ok := pub.(*ecdsa.PublicKey)
if !ok {
return nil, errors.New("marshal: data was not an ECDSA public key")
}
return ecdsaPub, nil
}
// EncodePublicKey encodes an ECDSA public key to PEM format.
func EncodePublicKey(key *ecdsa.PublicKey) ([]byte, error) {
derBytes, err := x509.MarshalPKIXPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
// DecodePrivateKey decodes a PEM-encoded ECDSA private key.
func DecodePrivateKey(encodedKey []byte) (*ecdsa.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "EC PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
privKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privKey, nil
}
// EncodePrivateKey encodes an ECDSA private key to PEM format.
func EncodePrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
derKey, err := x509.MarshalECPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: derKey,
}
return pem.EncodeToMemory(keyBlock), nil
}
// Encodes an ECDSA signature according to
// https://tools.ietf.org/html/rfc7515#appendix-A.3.1
func EncodeSignatureJWT(sig []byte) string {
return base64.RawURLEncoding.EncodeToString(sig)
}
// Decodes an ECDSA signature according to
// https://tools.ietf.org/html/rfc7515#appendix-A.3.1
func DecodeSignatureJWT(b64sig string) ([]byte, error) {
return base64.RawURLEncoding.DecodeString(b64sig)
}

133
vendor/github.com/gtank/cryptopasta/marshal_test.go generated vendored Normal file
View File

@@ -0,0 +1,133 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
package cryptopasta
import (
"bytes"
"strings"
"testing"
)
// A keypair for NIST P-256 / secp256r1
// Generated using:
// openssl ecparam -genkey -name prime256v1 -outform PEM
var pemECPrivateKeyP256 = `-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOI+EZsjyN3jvWJI/KDihFmqTuDpUe/if6f/pgGTBta/oAoGCCqGSM49
AwEHoUQDQgAEhhObKJ1r1PcUw+3REd/TbmSZnDvXnFUSTwqQFo5gbfIlP+gvEYba
+Rxj2hhqjfzqxIleRK40IRyEi3fJM/8Qhg==
-----END EC PRIVATE KEY-----
`
var pemECPublicKeyP256 = `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhhObKJ1r1PcUw+3REd/TbmSZnDvX
nFUSTwqQFo5gbfIlP+gvEYba+Rxj2hhqjfzqxIleRK40IRyEi3fJM/8Qhg==
-----END PUBLIC KEY-----
`
// A keypair for NIST P-384 / secp384r1
// Generated using:
// openssl ecparam -genkey -name secp384r1 -outform PEM
var pemECPrivateKeyP384 = `-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDAhA0YPVL1kimIy+FAqzUAtmR3It2Yjv2I++YpcC4oX7wGuEWcWKBYE
oOjj7wG/memgBwYFK4EEACKhZANiAAQub8xaaCTTW5rCHJCqUddIXpvq/TxdwViH
+tPEQQlJAJciXStM/aNLYA7Q1K1zMjYyzKSWz5kAh/+x4rXQ9Hlm3VAwCQDVVSjP
bfiNOXKOWfmyrGyQ7fQfs+ro1lmjLjs=
-----END EC PRIVATE KEY-----
`
var pemECPublicKeyP384 = `-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAELm/MWmgk01uawhyQqlHXSF6b6v08XcFY
h/rTxEEJSQCXIl0rTP2jS2AO0NStczI2Msykls+ZAIf/seK10PR5Zt1QMAkA1VUo
z234jTlyjln5sqxskO30H7Pq6NZZoy47
-----END PUBLIC KEY-----
`
var garbagePEM = `-----BEGIN GARBAGE-----
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=
-----END GARBAGE-----
`
func TestPublicKeyMarshaling(t *testing.T) {
ecKey, err := DecodePublicKey([]byte(pemECPublicKeyP256))
if err != nil {
t.Fatal(err)
}
pemBytes, _ := EncodePublicKey(ecKey)
if !bytes.Equal(pemBytes, []byte(pemECPublicKeyP256)) {
t.Fatal("public key encoding did not match")
}
}
func TestPrivateKeyBadDecode(t *testing.T) {
_, err := DecodePrivateKey([]byte(garbagePEM))
if err == nil {
t.Fatal("decoded garbage data without complaint")
}
}
func TestPrivateKeyMarshaling(t *testing.T) {
ecKey, err := DecodePrivateKey([]byte(pemECPrivateKeyP256))
if err != nil {
t.Fatal(err)
}
pemBytes, _ := EncodePrivateKey(ecKey)
if !strings.HasSuffix(pemECPrivateKeyP256, string(pemBytes)) {
t.Fatal("private key encoding did not match")
}
}
// Test vector from https://tools.ietf.org/html/rfc7515#appendix-A.3.1
var jwtTest = []struct {
sigBytes []byte
b64sig string
}{
{
sigBytes: []byte{14, 209, 33, 83, 121, 99, 108, 72, 60, 47, 127, 21,
88, 7, 212, 2, 163, 178, 40, 3, 58, 249, 124, 126, 23, 129, 154, 195, 22, 158,
166, 101, 197, 10, 7, 211, 140, 60, 112, 229, 216, 241, 45, 175,
8, 74, 84, 128, 166, 101, 144, 197, 242, 147, 80, 154, 143, 63, 127, 138, 131,
163, 84, 213},
b64sig: "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q",
},
}
func TestJWTEncoding(t *testing.T) {
for _, tt := range jwtTest {
result := EncodeSignatureJWT(tt.sigBytes)
if strings.Compare(result, tt.b64sig) != 0 {
t.Fatalf("expected %s, got %s\n", tt.b64sig, result)
}
}
}
func TestJWTDecoding(t *testing.T) {
for _, tt := range jwtTest {
resultSig, err := DecodeSignatureJWT(tt.b64sig)
if err != nil {
t.Error(err)
}
if !bytes.Equal(resultSig, tt.sigBytes) {
t.Fatalf("decoded signature was incorrect")
}
}
}

105
vendor/github.com/gtank/cryptopasta/sign.go generated vendored Normal file
View File

@@ -0,0 +1,105 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides message authentication and asymmetric signatures.
//
// Message authentication: HMAC SHA512/256
// This is a slight twist on the highly dependable HMAC-SHA256 that gains
// performance on 64-bit systems and consistency with our hashing
// recommendation.
//
// Asymmetric Signature: ECDSA using P256 and SHA256
// ECDSA is the best compromise between cryptographic concerns and support for
// our internal use cases (e.g. RFC7518). The Go standard library
// implementation has some protection against entropy problems, but is not
// deterministic. See
// https://github.com/golang/go/commit/8d7bf2291b095d3a2ecaa2609e1101be46d80deb
package cryptopasta
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"io"
"math/big"
)
// NewHMACKey generates a random 256-bit secret key for HMAC use.
// Because key generation is critical, it panics if the source of randomness fails.
func NewHMACKey() *[32]byte {
key := &[32]byte{}
_, err := io.ReadFull(rand.Reader, key[:])
if err != nil {
panic(err)
}
return key
}
// GenerateHMAC produces a symmetric signature using a shared secret key.
func GenerateHMAC(data []byte, key *[32]byte) []byte {
h := hmac.New(sha512.New512_256, key[:])
h.Write(data)
return h.Sum(nil)
}
// CheckHMAC securely checks the supplied MAC against a message using the shared secret key.
func CheckHMAC(data, suppliedMAC []byte, key *[32]byte) bool {
expectedMAC := GenerateHMAC(data, key)
return hmac.Equal(expectedMAC, suppliedMAC)
}
// GenerateSigningKey generates a random P-256 ECDSA private key.
func NewSigningKey() (*ecdsa.PrivateKey, error) {
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
return key, err
}
// Sign signs arbitrary data using ECDSA.
func Sign(data []byte, privkey *ecdsa.PrivateKey) ([]byte, error) {
// hash message
digest := sha256.Sum256(data)
// sign the hash
r, s, err := ecdsa.Sign(rand.Reader, privkey, digest[:])
if err != nil {
return nil, err
}
// encode the signature {R, S}
// big.Int.Bytes() will need padding in the case of leading zero bytes
params := privkey.Curve.Params()
curveOrderByteSize := params.P.BitLen() / 8
rBytes, sBytes := r.Bytes(), s.Bytes()
signature := make([]byte, curveOrderByteSize*2)
copy(signature[curveOrderByteSize-len(rBytes):], rBytes)
copy(signature[curveOrderByteSize*2-len(sBytes):], sBytes)
return signature, nil
}
// Verify checks a raw ECDSA signature.
// Returns true if it's valid and false if not.
func Verify(data, signature []byte, pubkey *ecdsa.PublicKey) bool {
// hash message
digest := sha256.Sum256(data)
curveOrderByteSize := pubkey.Curve.Params().P.BitLen() / 8
r, s := new(big.Int), new(big.Int)
r.SetBytes(signature[:curveOrderByteSize])
s.SetBytes(signature[curveOrderByteSize:])
return ecdsa.Verify(pubkey, digest[:], r, s)
}

107
vendor/github.com/gtank/cryptopasta/sign_test.go generated vendored Normal file
View File

@@ -0,0 +1,107 @@
// cryptopasta - basic cryptography examples
//
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
package cryptopasta
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/hex"
"testing"
)
// https://groups.google.com/d/msg/sci.crypt/OolWgsgQD-8/jHciyWkaL0gJ
var hmacTests = []struct {
key string
data string
digest string
}{
{
key: "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
data: "4869205468657265", // "Hi There"
digest: "9f9126c3d9c3c330d760425ca8a217e31feae31bfe70196ff81642b868402eab",
},
{
key: "4a656665", // "Jefe"
data: "7768617420646f2079612077616e7420666f72206e6f7468696e673f", // "what do ya want for nothing?"
digest: "6df7b24630d5ccb2ee335407081a87188c221489768fa2020513b2d593359456",
},
}
func TestHMAC(t *testing.T) {
for idx, tt := range hmacTests {
keySlice, _ := hex.DecodeString(tt.key)
dataBytes, _ := hex.DecodeString(tt.data)
expectedDigest, _ := hex.DecodeString(tt.digest)
keyBytes := &[32]byte{}
copy(keyBytes[:], keySlice)
macDigest := GenerateHMAC(dataBytes, keyBytes)
if !bytes.Equal(macDigest, expectedDigest) {
t.Errorf("test %d generated unexpected mac", idx)
}
}
}
func TestSign(t *testing.T) {
message := []byte("Hello, world!")
key, err := NewSigningKey()
if err != nil {
t.Error(err)
return
}
signature, err := Sign(message, key)
if err != nil {
t.Error(err)
return
}
if !Verify(message, signature, &key.PublicKey) {
t.Error("signature was not correct")
return
}
message[0] ^= 0xff
if Verify(message, signature, &key.PublicKey) {
t.Error("signature was good for altered message")
}
}
func TestSignWithP384(t *testing.T) {
message := []byte("Hello, world!")
key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
t.Error(err)
return
}
signature, err := Sign(message, key)
if err != nil {
t.Error(err)
return
}
if !Verify(message, signature, &key.PublicKey) {
t.Error("signature was not correct")
return
}
message[0] ^= 0xff
if Verify(message, signature, &key.PublicKey) {
t.Error("signature was good for altered message")
}
}

BIN
vendor/github.com/gtank/cryptopasta/testdata/big generated vendored Normal file

Binary file not shown.

BIN
vendor/github.com/gtank/cryptopasta/testdata/random generated vendored Normal file

Binary file not shown.

29
vendor/github.com/gtank/cryptopasta/tls.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
// cryptopasta - basic cryptography examples
//
// Written in 2016 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides a recommended TLS configuration.
package cryptopasta
import "crypto/tls"
func DefaultTLSConfig() *tls.Config {
return &tls.Config{
// Avoids most of the memorably-named TLS attacks
MinVersion: tls.VersionTLS12,
// Causes servers to use Go's default ciphersuite preferences,
// which are tuned to avoid attacks. Does nothing on clients.
PreferServerCipherSuites: true,
// Only use curves which have constant-time implementations
CurvePreferences: []tls.CurveID{
tls.CurveP256,
},
}
}

38
vendor/github.com/gtank/cryptopasta/tls_test.go generated vendored Normal file
View File

@@ -0,0 +1,38 @@
// cryptopasta - basic cryptography examples
//
// Written in 2016 by George Tankersley <george.tankersley@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
// Provides a recommended TLS configuration.
package cryptopasta
import (
"log"
"net/http"
)
func ExampleTLSServer() {
// Get recommended basic configuration
config := DefaultTLSConfig()
// Serve up some HTTP
http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte("Hello, world\n"))
})
server := &http.Server{
Addr: ":8080",
TLSConfig: config,
}
err := server.ListenAndServeTLS("cert.pem", "key.pem")
if err != nil {
log.Fatal(err)
}
}