carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1// Package signtest stands in for AWS's instance-identity signer: one key,
2// one self-signed certificate, and identity documents signed with them. It
3// imports nothing from boxid, so both boxid's own tests (package boxid) and
4// boxid/boxidtest wrap it without an import cycle.
5package signtest
6
7import (
8 "crypto"
9 "crypto/rand"
10 "crypto/rsa"
11 "crypto/sha256"
12 "crypto/x509"
13 "crypto/x509/pkix"
14 "encoding/json"
15 "math/big"
16 "testing"
17 "time"
18)
19
20// Signer is one test's AWS.
21type Signer struct {
22 Key *rsa.PrivateKey
23 Cert *x509.Certificate
24}
25
26// New makes a fresh key and a certificate for it, valid for an hour either
27// side of now.
28func New(t testing.TB) *Signer {
29 t.Helper()
30 key, err := rsa.GenerateKey(rand.Reader, 2048)
31 if err != nil {
32 t.Fatal(err)
33 }
34 tmpl := &x509.Certificate{SerialNumber: big.NewInt(1), Subject: pkix.Name{CommonName: "test"},
35 NotBefore: time.Now().Add(-time.Hour), NotAfter: time.Now().Add(time.Hour)}
36 der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
37 if err != nil {
38 t.Fatal(err)
39 }
40 cert, err := x509.ParseCertificate(der)
41 if err != nil {
42 t.Fatal(err)
43 }
44 return &Signer{Key: key, Cert: cert}
45}
46
47// Sign returns an identity document for instance in account and region and
48// its PKCS #1 v1.5 SHA-256 signature, the pair AWS's IMDS serves.
49func (s *Signer) Sign(t testing.TB, account, region, instance string) (doc, sig []byte) {
50 t.Helper()
51 doc, err := json.Marshal(map[string]string{"accountId": account, "region": region, "instanceId": instance})
52 if err != nil {
53 t.Fatal(err)
54 }
55 sum := sha256.Sum256(doc)
56 sig, err = rsa.SignPKCS1v15(rand.Reader, s.Key, crypto.SHA256, sum[:])
57 if err != nil {
58 t.Fatal(err)
59 }
60 return doc, sig
61}
62