2018-07-09 18:43:13 +01:00
|
|
|
// Copyright (C) 2018 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package peertls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
func TestNewCert_CA(t *testing.T) {
|
2018-08-13 09:39:45 +01:00
|
|
|
k, err := NewKey()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
ct, err := CATemplate()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
p, _ := k.(*ecdsa.PrivateKey)
|
|
|
|
c, err := NewCert(ct, nil, &p.PublicKey, k)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
assert.NotEmpty(t, k.(*ecdsa.PrivateKey))
|
|
|
|
assert.NotEmpty(t, c)
|
|
|
|
assert.NotEmpty(t, c.PublicKey.(*ecdsa.PublicKey))
|
2018-07-09 18:43:13 +01:00
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
err = c.CheckSignatureFrom(c)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
func TestNewCert_Leaf(t *testing.T) {
|
2018-08-13 09:39:45 +01:00
|
|
|
k, err := NewKey()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
ct, err := CATemplate()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
cp, _ := k.(*ecdsa.PrivateKey)
|
|
|
|
c, err := NewCert(ct, nil, &cp.PublicKey, k)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
lt, err := LeafTemplate()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
lp, _ := k.(*ecdsa.PrivateKey)
|
|
|
|
l, err := NewCert(lt, ct, &lp.PublicKey, k)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
assert.NotEmpty(t, k.(*ecdsa.PrivateKey))
|
|
|
|
assert.NotEmpty(t, l)
|
|
|
|
assert.NotEmpty(t, l.PublicKey.(*ecdsa.PublicKey))
|
2018-07-09 18:43:13 +01:00
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
err = c.CheckSignatureFrom(c)
|
|
|
|
assert.NoError(t, err)
|
2018-08-13 09:39:45 +01:00
|
|
|
err = l.CheckSignatureFrom(c)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
func TestVerifyPeerFunc(t *testing.T) {
|
|
|
|
k, err := NewKey()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
ct, err := CATemplate()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
cp, _ := k.(*ecdsa.PrivateKey)
|
|
|
|
c, err := NewCert(ct, nil, &cp.PublicKey, k)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
lt, err := LeafTemplate()
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-23 15:08:26 +01:00
|
|
|
lp, _ := k.(*ecdsa.PrivateKey)
|
|
|
|
l, err := NewCert(lt, ct, &lp.PublicKey, k)
|
2018-07-09 18:43:13 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
testFunc := func(chain [][]byte, parsedChains [][]*x509.Certificate) error {
|
|
|
|
switch {
|
2018-08-27 18:28:16 +01:00
|
|
|
case !bytes.Equal(chain[1], c.Raw):
|
2018-08-13 09:39:45 +01:00
|
|
|
return errs.New("CA cert doesn't match")
|
2018-08-27 18:28:16 +01:00
|
|
|
case !bytes.Equal(chain[0], l.Raw):
|
2018-08-13 09:39:45 +01:00
|
|
|
return errs.New("leaf's CA cert doesn't match")
|
|
|
|
case l.PublicKey.(*ecdsa.PublicKey).Curve != parsedChains[0][0].PublicKey.(*ecdsa.PublicKey).Curve:
|
|
|
|
return errs.New("leaf public key doesn't match")
|
|
|
|
case l.PublicKey.(*ecdsa.PublicKey).X.Cmp(parsedChains[0][0].PublicKey.(*ecdsa.PublicKey).X) != 0:
|
|
|
|
return errs.New("leaf public key doesn't match")
|
|
|
|
case l.PublicKey.(*ecdsa.PublicKey).Y.Cmp(parsedChains[0][0].PublicKey.(*ecdsa.PublicKey).Y) != 0:
|
|
|
|
return errs.New("leaf public key doesn't match")
|
2018-08-27 18:28:16 +01:00
|
|
|
case !bytes.Equal(parsedChains[0][1].Raw, c.Raw):
|
2018-08-13 09:39:45 +01:00
|
|
|
return errs.New("parsed CA cert doesn't match")
|
2018-08-27 18:28:16 +01:00
|
|
|
case !bytes.Equal(parsedChains[0][0].Raw, l.Raw):
|
2018-08-13 09:39:45 +01:00
|
|
|
return errs.New("parsed leaf cert doesn't match")
|
|
|
|
}
|
|
|
|
return nil
|
2018-07-09 18:43:13 +01:00
|
|
|
}
|
|
|
|
|
2018-08-13 09:39:45 +01:00
|
|
|
err = VerifyPeerFunc(testFunc)([][]byte{l.Raw, c.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
2018-07-09 18:43:13 +01:00
|
|
|
}
|
2018-08-23 15:08:26 +01:00
|
|
|
|
|
|
|
func TestVerifyPeerCertChains(t *testing.T) {
|
|
|
|
k, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ct, err := CATemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
cp, ok := k.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
c, err := NewCert(ct, nil, &cp.PublicKey, k)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
lt, err := LeafTemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
lp, ok := k.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
l, err := NewCert(lt, ct, &lp.PublicKey, k)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyPeerCertChains)([][]byte{l.Raw, c.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
2018-10-26 14:52:37 +01:00
|
|
|
|
|
|
|
c, err = NewCert(ct, nil, &cp.PublicKey, k)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
k2, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
l, err = NewCert(lt, nil, &lp.PublicKey, k2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyPeerCertChains)([][]byte{l.Raw, c.Raw}, nil)
|
|
|
|
assert.True(t, ErrVerifyPeerCert.Has(err))
|
|
|
|
assert.True(t, ErrVerifyCertificateChain.Has(err))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVerifyCAWhitelist(t *testing.T) {
|
|
|
|
k, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ct, err := CATemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
cp, ok := k.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
c, err := NewCert(ct, nil, &cp.PublicKey, k)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
lt, err := LeafTemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
lk, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
lp, ok := lk.(*ecdsa.PrivateKey)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.True(t, ok)
|
2018-11-01 15:48:43 +00:00
|
|
|
|
2018-10-26 14:52:37 +01:00
|
|
|
l, err := NewCert(lt, ct, &lp.PublicKey, k)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist(nil, false))([][]byte{l.Raw, c.Raw}, nil)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{c}, false))([][]byte{l.Raw, c.Raw}, nil)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
zk, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
zt, err := CATemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
zp, ok := zk.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
z, err := NewCert(zt, nil, &zp.PublicKey, zk)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{z}, false))([][]byte{l.Raw, c.Raw}, nil)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.True(t, ErrVerifyCAWhitelist.Has(err))
|
|
|
|
assert.True(t, ErrVerifySignature.Has(err))
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{z, c}, false))([][]byte{l.Raw, c.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{c, z}, false))([][]byte{l.Raw, c.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
xt, err := LeafTemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
xk, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
xp, ok := xk.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
|
|
|
x, err := NewCert(xt, zt, &xp.PublicKey, zk)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
yt, err := LeafTemplate()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
yk, err := NewKey()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
yp, ok := yk.(*ecdsa.PrivateKey)
|
|
|
|
assert.True(t, ok)
|
|
|
|
y, err := NewCert(yt, xt, &yp.PublicKey, xk)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{z, c}, false))([][]byte{z.Raw, x.Raw, y.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{c, z}, false))([][]byte{z.Raw, x.Raw, y.Raw}, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{z, c}, true))([][]byte{z.Raw, x.Raw, y.Raw}, nil)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2018-11-01 15:48:43 +00:00
|
|
|
err = VerifyPeerFunc(VerifyCAWhitelist([]*x509.Certificate{c, z}, true))([][]byte{z.Raw, x.Raw, y.Raw}, nil)
|
2018-10-26 14:52:37 +01:00
|
|
|
assert.NoError(t, err)
|
2018-08-23 15:08:26 +01:00
|
|
|
}
|