| 12
 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)
}
 |