-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into ui/redesign-transit
- Loading branch information
Showing
10 changed files
with
808 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# MongoDB Tests | ||
The test `TestInit_clientTLS` cannot be run within CircleCI in its current form. This is because [it's not | ||
possible to use volume mounting with the docker executor](https://support.circleci.com/hc/en-us/articles/360007324514-How-can-I-mount-volumes-to-docker-containers-). | ||
|
||
Because of this, the test is skipped. Running this locally shouldn't present any issues as long as you have | ||
docker set up to allow volume mounting from this directory: | ||
|
||
```sh | ||
go test -v -run Init_clientTLS | ||
``` | ||
|
||
This may be able to be fixed if we mess with the entrypoint or the command arguments. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
package mongodb | ||
|
||
import ( | ||
"bytes" | ||
"crypto" | ||
"crypto/rand" | ||
"crypto/rsa" | ||
"crypto/sha1" | ||
"crypto/tls" | ||
"crypto/x509" | ||
"crypto/x509/pkix" | ||
"encoding/pem" | ||
"io/ioutil" | ||
"math/big" | ||
"os" | ||
"strings" | ||
"testing" | ||
"time" | ||
) | ||
|
||
type certBuilder struct { | ||
tmpl *x509.Certificate | ||
parentTmpl *x509.Certificate | ||
|
||
selfSign bool | ||
parentKey *rsa.PrivateKey | ||
|
||
isCA bool | ||
} | ||
|
||
type certOpt func(*certBuilder) error | ||
|
||
func commonName(cn string) certOpt { | ||
return func(builder *certBuilder) error { | ||
builder.tmpl.Subject.CommonName = cn | ||
return nil | ||
} | ||
} | ||
|
||
func parent(parent certificate) certOpt { | ||
return func(builder *certBuilder) error { | ||
builder.parentKey = parent.privKey.privKey | ||
builder.parentTmpl = parent.template | ||
return nil | ||
} | ||
} | ||
|
||
func isCA(isCA bool) certOpt { | ||
return func(builder *certBuilder) error { | ||
builder.isCA = isCA | ||
return nil | ||
} | ||
} | ||
|
||
func selfSign() certOpt { | ||
return func(builder *certBuilder) error { | ||
builder.selfSign = true | ||
return nil | ||
} | ||
} | ||
|
||
func dns(dns ...string) certOpt { | ||
return func(builder *certBuilder) error { | ||
builder.tmpl.DNSNames = dns | ||
return nil | ||
} | ||
} | ||
|
||
func newCert(t *testing.T, opts ...certOpt) (cert certificate) { | ||
t.Helper() | ||
|
||
builder := certBuilder{ | ||
tmpl: &x509.Certificate{ | ||
SerialNumber: makeSerial(t), | ||
Subject: pkix.Name{ | ||
CommonName: makeCommonName(), | ||
}, | ||
NotBefore: time.Now().Add(-1 * time.Hour), | ||
NotAfter: time.Now().Add(1 * time.Hour), | ||
IsCA: false, | ||
KeyUsage: x509.KeyUsageDigitalSignature | | ||
x509.KeyUsageKeyEncipherment | | ||
x509.KeyUsageKeyAgreement, | ||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, | ||
BasicConstraintsValid: true, | ||
}, | ||
} | ||
|
||
for _, opt := range opts { | ||
err := opt(&builder) | ||
if err != nil { | ||
t.Fatalf("Failed to set up certificate builder: %s", err) | ||
} | ||
} | ||
|
||
key := newPrivateKey(t) | ||
|
||
builder.tmpl.SubjectKeyId = getSubjKeyID(t, key.privKey) | ||
|
||
tmpl := builder.tmpl | ||
parent := builder.parentTmpl | ||
publicKey := key.privKey.Public() | ||
signingKey := builder.parentKey | ||
|
||
if builder.selfSign { | ||
parent = tmpl | ||
signingKey = key.privKey | ||
} | ||
|
||
if builder.isCA { | ||
tmpl.IsCA = true | ||
tmpl.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageCRLSign | ||
tmpl.ExtKeyUsage = nil | ||
} else { | ||
tmpl.KeyUsage = x509.KeyUsageDigitalSignature | | ||
x509.KeyUsageKeyEncipherment | | ||
x509.KeyUsageKeyAgreement | ||
tmpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth} | ||
} | ||
|
||
certBytes, err := x509.CreateCertificate(rand.Reader, tmpl, parent, publicKey, signingKey) | ||
if err != nil { | ||
t.Fatalf("Unable to generate certificate: %s", err) | ||
} | ||
certPem := pem.EncodeToMemory(&pem.Block{ | ||
Type: "CERTIFICATE", | ||
Bytes: certBytes, | ||
}) | ||
|
||
tlsCert, err := tls.X509KeyPair(certPem, key.pem) | ||
if err != nil { | ||
t.Fatalf("Unable to parse X509 key pair: %s", err) | ||
} | ||
|
||
return certificate{ | ||
template: tmpl, | ||
privKey: key, | ||
tlsCert: tlsCert, | ||
rawCert: certBytes, | ||
pem: certPem, | ||
isCA: builder.isCA, | ||
} | ||
} | ||
|
||
// //////////////////////////////////////////////////////////////////////////// | ||
// Private Key | ||
// //////////////////////////////////////////////////////////////////////////// | ||
type keyWrapper struct { | ||
privKey *rsa.PrivateKey | ||
pem []byte | ||
} | ||
|
||
func newPrivateKey(t *testing.T) (key keyWrapper) { | ||
t.Helper() | ||
|
||
privKey, err := rsa.GenerateKey(rand.Reader, 2048) | ||
if err != nil { | ||
t.Fatalf("Unable to generate key for cert: %s", err) | ||
} | ||
|
||
privKeyPem := pem.EncodeToMemory( | ||
&pem.Block{ | ||
Type: "RSA PRIVATE KEY", | ||
Bytes: x509.MarshalPKCS1PrivateKey(privKey), | ||
}, | ||
) | ||
|
||
key = keyWrapper{ | ||
privKey: privKey, | ||
pem: privKeyPem, | ||
} | ||
|
||
return key | ||
} | ||
|
||
// //////////////////////////////////////////////////////////////////////////// | ||
// Certificate | ||
// //////////////////////////////////////////////////////////////////////////// | ||
type certificate struct { | ||
privKey keyWrapper | ||
template *x509.Certificate | ||
tlsCert tls.Certificate | ||
rawCert []byte | ||
pem []byte | ||
isCA bool | ||
} | ||
|
||
func (cert certificate) CombinedPEM() []byte { | ||
if cert.isCA { | ||
return cert.pem | ||
} | ||
return bytes.Join([][]byte{cert.privKey.pem, cert.pem}, []byte{'\n'}) | ||
} | ||
|
||
// //////////////////////////////////////////////////////////////////////////// | ||
// Writing to file | ||
// //////////////////////////////////////////////////////////////////////////// | ||
func writeFile(t *testing.T, filename string, data []byte, perms os.FileMode) { | ||
t.Helper() | ||
|
||
err := ioutil.WriteFile(filename, data, perms) | ||
if err != nil { | ||
t.Fatalf("Unable to write to file [%s]: %s", filename, err) | ||
} | ||
} | ||
|
||
// //////////////////////////////////////////////////////////////////////////// | ||
// Helpers | ||
// //////////////////////////////////////////////////////////////////////////// | ||
func makeSerial(t *testing.T) *big.Int { | ||
t.Helper() | ||
|
||
v := &big.Int{} | ||
serialNumberLimit := v.Lsh(big.NewInt(1), 128) | ||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) | ||
if err != nil { | ||
t.Fatalf("Unable to generate serial number: %s", err) | ||
} | ||
return serialNumber | ||
} | ||
|
||
// Pulled from sdk/helper/certutil & slightly modified for test usage | ||
func getSubjKeyID(t *testing.T, privateKey crypto.Signer) []byte { | ||
t.Helper() | ||
|
||
if privateKey == nil { | ||
t.Fatalf("passed-in private key is nil") | ||
} | ||
|
||
marshaledKey, err := x509.MarshalPKIXPublicKey(privateKey.Public()) | ||
if err != nil { | ||
t.Fatalf("error marshalling public key: %s", err) | ||
} | ||
|
||
subjKeyID := sha1.Sum(marshaledKey) | ||
|
||
return subjKeyID[:] | ||
} | ||
|
||
func makeCommonName() (cn string) { | ||
return strings.ReplaceAll(time.Now().Format("20060102T150405.000"), ".", "") | ||
} |
Oops, something went wrong.