1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
package storage
import (
"crypto/x509"
"encoding/json"
"fmt"
"time"
)
// AK is the type used to store AKs.
type AK struct {
Name string
Data []byte
Chain []*x509.Certificate
CreatedAt time.Time
}
// MarshalJSON marshals the AK into JSON.
func (ak *AK) MarshalJSON() ([]byte, error) {
chain := make([][]byte, len(ak.Chain))
for i, cert := range ak.Chain {
chain[i] = cert.Raw
}
sak := serializedAK{
Name: ak.Name,
Type: typeAK,
Data: ak.Data,
CreatedAt: ak.CreatedAt,
}
if len(chain) > 0 {
sak.Chain = chain
}
return json.Marshal(sak)
}
// UnmarshalJSON unmarshals `data` into an AK.
func (ak *AK) UnmarshalJSON(data []byte) error {
sak := &serializedAK{}
if err := json.Unmarshal(data, sak); err != nil {
return fmt.Errorf("failed unmarshaling serialized AK: %w", err)
}
if sak.Type != typeAK {
return fmt.Errorf("unexpected serialized data type %q", sak.Type)
}
ak.Name = sak.Name
ak.Data = sak.Data
ak.CreatedAt = sak.CreatedAt
if len(sak.Chain) > 0 {
chain := make([]*x509.Certificate, len(sak.Chain))
for i, certBytes := range sak.Chain {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return fmt.Errorf("failed parsing certificate: %w", err)
}
chain[i] = cert
}
ak.Chain = chain
}
return nil
}
// Key is the type used to store Keys.
type Key struct {
Name string
Data []byte
AttestedBy string
Chain []*x509.Certificate
CreatedAt time.Time
}
// MarshalJSON marshals the Key into JSON.
func (key *Key) MarshalJSON() ([]byte, error) {
chain := make([][]byte, len(key.Chain))
for i, cert := range key.Chain {
chain[i] = cert.Raw
}
sk := serializedKey{
Name: key.Name,
Type: typeKey,
Data: key.Data,
AttestedBy: key.AttestedBy,
CreatedAt: key.CreatedAt,
}
if len(chain) > 0 {
sk.Chain = chain
}
return json.Marshal(sk)
}
// UnmarshalJSON unmarshals `data` into a Key.
func (key *Key) UnmarshalJSON(data []byte) error {
sk := &serializedKey{}
if err := json.Unmarshal(data, sk); err != nil {
return fmt.Errorf("failed unmarshaling serialized key: %w", err)
}
if sk.Type != typeKey {
return fmt.Errorf("unexpected serialized data type %q", sk.Type)
}
key.Name = sk.Name
key.Data = sk.Data
key.AttestedBy = sk.AttestedBy
key.CreatedAt = sk.CreatedAt
if len(sk.Chain) > 0 {
chain := make([]*x509.Certificate, len(sk.Chain))
for i, certBytes := range sk.Chain {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return fmt.Errorf("failed parsing certificate: %w", err)
}
chain[i] = cert
}
key.Chain = chain
}
return nil
}
const (
akPrefix = "ak-"
keyPrefix = "key-"
)
type tpmObjectType string
const (
typeAK tpmObjectType = "AK"
typeKey tpmObjectType = "KEY"
)
// serializedAK is the struct used when marshaling
// a storage AK to JSON.
type serializedAK struct {
Name string `json:"name"`
Type tpmObjectType `json:"type"`
Data []byte `json:"data"`
Chain [][]byte `json:"chain"`
CreatedAt time.Time `json:"createdAt"`
}
// serializedKey is the struct used when marshaling
// a storage Key to JSON.
type serializedKey struct {
Name string `json:"name"`
Type tpmObjectType `json:"type"`
Data []byte `json:"data"`
AttestedBy string `json:"attestedBy"`
Chain [][]byte `json:"chain"`
CreatedAt time.Time `json:"createdAt"`
}
// keyForAK returns the key to use when storing an AK.
func keyForAK(name string) string {
return fmt.Sprintf("%s%s", akPrefix, name)
}
// keyForKey returns the key to use when storing a Key.
func keyForKey(name string) string {
return fmt.Sprintf("%s%s", keyPrefix, name)
}
|