File: extension.go

package info (click to toggle)
golang-github-smallstep-crypto 0.57.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,284 kB
  • sloc: sh: 53; makefile: 36
file content (191 lines) | stat: -rw-r--r-- 5,868 bytes parent folder | download | duplicates (2)
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//nolint:unused // ignore unused types for now
package skae

import (
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"errors"
	"math/big"

	"github.com/smallstep/go-attestation/attest"
)

var (
	oidSubjectKeyAttestationEvidence = asn1.ObjectIdentifier{2, 23, 133, 6, 1, 1} // SKAE (Subject Key Attestation Evidence) OID: 2.23.133.6.1.1
	oidAuthorityInfoAccessOcsp       = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
	oidAuthorityInfoAccessIssuers    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
)

func CreateSubjectKeyAttestationEvidenceExtension(_ *x509.Certificate, _ attest.CertificationParameters, _ bool) (pkix.Extension, error) {
	return pkix.Extension{}, errors.New("not implemented yet") // return early; not verified to be working as expected yet

	/*
		asn1Issuer, err := asn1.Marshal(akCert.Issuer.ToRDNSequence()) //nolint:govet // intentionally breaking early
		if err != nil {
			return pkix.Extension{}, fmt.Errorf("error marshaling issuer: %w", err)
		}

		skaeExtension := asn1SKAE{
			TCGSpecVersion:         asn1TCGSpecVersion{Major: 2, Minor: 0},
			KeyAttestationEvidence: asn1KeyAttestationEvidence{},
		}

		attestationEvidence := asn1AttestationEvidence{
			TPMCertifyInfo: asn1TPMCertifyInfo{
				CertifyInfo: asn1.BitString{ // TODO: check if setting the values like this is correct
					Bytes:     params.CreateAttestation,
					BitLength: len(params.CreateAttestation) * 8,
				},
				Signature: asn1.BitString{
					Bytes:     params.CreateSignature,
					BitLength: len(params.CreateSignature) * 8,
				},
			},
			TPMIdentityCredAccessInfo: asn1TPMIdentityCredentialAccessInfo{
				AuthorityInfoAccess: createAIA(akCert),
				IssuerSerial: issuerAndSerial{
					IssuerName:   asn1.RawValue{FullBytes: asn1Issuer},
					SerialNumber: akCert.SerialNumber,
				},
			},
		}

		aeb, err := asn1.Marshal(attestationEvidence)
		if err != nil {
			return pkix.Extension{}, fmt.Errorf("error marshaling attestation evidence: %w", err)
		}

		if !shouldEncrypt {
			//skaeExtension.KeyAttestationEvidence.AttestEvidence = attestationEvidence
			skaeExtension.KeyAttestationEvidence.Evidence = asn1.RawValue{
				Class:      asn1.ClassContextSpecific,
				IsCompound: true,
				Tag:        0, // CHOICE "0"
				Bytes:      aeb,
			}
		} else {
			// TODO: encrypt the AttestEvidence to (right) recipient; set it as the EnvelopedAttestEvidence
			encryptedAEB := aeb

			eae := asn1EnvelopedAttestationEvidence{
				RecipientInfos: []recipientInfo{}, // TODO: fill recipient(s)
				EncryptedAttestInfo: asn1EncryptedAttestationInfo{
					EncryptionAlgorithm: pkix.AlgorithmIdentifier{
						Algorithm: nil, // TODO: select and fill
					},
					EncryptedAttestEvidence: encryptedAEB,
				},
			}

			eaeBytes, err := asn1.Marshal(eae)
			if err != nil {
				return pkix.Extension{}, errors.New("error marshaling EnvelopedAttestationEvidence")
			}

			skaeExtension.KeyAttestationEvidence.Evidence = asn1.RawValue{
				Class:      asn1.ClassContextSpecific,
				IsCompound: true,
				Tag:        1, // CHOICE "1"
				Bytes:      eaeBytes,
			}

			return pkix.Extension{}, errors.New("encrypting the AttestEvidence is not yet supported")
		}

		skaeExtensionBytes, err := asn1.Marshal(skaeExtension)
		if err != nil {
			return pkix.Extension{}, fmt.Errorf("creating SKAE extension failed: %w", err)
		}

		result := pkix.Extension{
			Id:       oidSubjectKeyAttestationEvidence,
			Critical: false, // non standard extension; don't break clients
			Value:    skaeExtensionBytes,
		}

		b, err := asn1.Marshal(result)
		if err != nil {
			return result, err
		}

		_ = b

		return result, nil
	*/
}

func createAIA(ak *x509.Certificate) []asn1AuthorityInfoAccessSyntax {
	var aiaValues []asn1AuthorityInfoAccessSyntax
	for _, server := range ak.OCSPServer {
		aiaValues = append(aiaValues, asn1AuthorityInfoAccessSyntax{
			Method:   oidAuthorityInfoAccessOcsp,
			Location: asn1.RawValue{Tag: asn1.TagOID, Class: asn1.ClassContextSpecific, Bytes: []byte(server)},
		})
	}
	for _, url := range ak.IssuingCertificateURL {
		aiaValues = append(aiaValues, asn1AuthorityInfoAccessSyntax{
			Method:   oidAuthorityInfoAccessIssuers,
			Location: asn1.RawValue{Tag: asn1.TagOID, Class: asn1.ClassContextSpecific, Bytes: []byte(url)},
		})
	}
	return aiaValues
}

type asn1SKAE struct {
	TCGSpecVersion         asn1TCGSpecVersion
	KeyAttestationEvidence asn1KeyAttestationEvidence
}

type asn1TCGSpecVersion struct {
	Major int
	Minor int
}

type asn1KeyAttestationEvidence struct {
	// AttestEvidence          asn1AttestationEvidence // TODO: ASN1 CHOICE between those two
	// EnvelopedAttestEvidence asn1EnvelopedAttestationEvidence
	Evidence asn1.RawValue
}

type asn1AttestationEvidence struct {
	TPMCertifyInfo            asn1TPMCertifyInfo
	TPMIdentityCredAccessInfo asn1TPMIdentityCredentialAccessInfo
}

type asn1TPMCertifyInfo struct {
	CertifyInfo asn1.BitString
	Signature   asn1.BitString
}

type asn1TPMIdentityCredentialAccessInfo struct {
	AuthorityInfoAccess []asn1AuthorityInfoAccessSyntax
	IssuerSerial        issuerAndSerial
}

type asn1AuthorityInfoAccessSyntax struct {
	Method   asn1.ObjectIdentifier
	Location asn1.RawValue
}

type issuerAndSerial struct {
	IssuerName   asn1.RawValue
	SerialNumber *big.Int
}

type asn1EnvelopedAttestationEvidence struct {
	RecipientInfos      []recipientInfo `asn1:"set"`
	EncryptedAttestInfo asn1EncryptedAttestationInfo
}

type recipientInfo struct {
	Version                int
	IssuerAndSerialNumber  issuerAndSerial
	KeyEncryptionAlgorithm pkix.AlgorithmIdentifier
	EncryptedKey           []byte
}

type asn1EncryptedAttestationInfo struct {
	EncryptionAlgorithm     pkix.AlgorithmIdentifier
	EncryptedAttestEvidence []byte // -- The ciphertext resulting from the encryption of DER-encoded AttestationEvidence (against public key in recipientinfo; something like that)
}