134 lines
3.8 KiB
Go
134 lines
3.8 KiB
Go
// 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")
|
|
}
|
|
}
|
|
}
|