2024-04-17 12:00:34 +00:00
|
|
|
package signatures
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/x509"
|
|
|
|
"fmt"
|
|
|
|
"github.com/foxboron/go-uefi/efi"
|
|
|
|
"github.com/foxboron/go-uefi/efi/signature"
|
|
|
|
"github.com/foxboron/go-uefi/efi/util"
|
|
|
|
"github.com/kairos-io/kairos-sdk/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GetKeyDatabase returns a single signature.SignatureDatabase for a given type
|
|
|
|
func GetKeyDatabase(sigType string) (*signature.SignatureDatabase, error) {
|
|
|
|
var err error
|
|
|
|
var sig *signature.SignatureDatabase
|
|
|
|
|
|
|
|
switch sigType {
|
|
|
|
case "PK", "pk":
|
|
|
|
sig, err = efi.GetPK()
|
|
|
|
case "KEK", "kek":
|
|
|
|
sig, err = efi.GetKEK()
|
|
|
|
case "DB", "db":
|
|
|
|
sig, err = efi.Getdb()
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("signature type unkown (%s). Valid signature types are PK,KEK,DB", sigType)
|
|
|
|
}
|
|
|
|
|
|
|
|
return sig, err
|
|
|
|
}
|
|
|
|
|
2024-04-18 13:11:52 +00:00
|
|
|
// GetAllFullCerts returns a list of certs in the system. Full cert, including raw data of the cert
|
|
|
|
func GetAllFullCerts() (types.CertListFull, error) {
|
|
|
|
var certList types.CertListFull
|
|
|
|
pk, err := GetKeyDatabase("PK")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
kek, err := GetKeyDatabase("KEK")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
db, err := GetKeyDatabase("DB")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
|
|
|
|
certList.PK = ExtractCertsFromSignatureDatabase(pk)
|
|
|
|
certList.KEK = ExtractCertsFromSignatureDatabase(kek)
|
|
|
|
certList.DB = ExtractCertsFromSignatureDatabase(db)
|
|
|
|
|
|
|
|
return certList, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExtractCertsFromSignatureDatabase returns a []*x509.Certificate from a *signature.SignatureDatabase
|
|
|
|
func ExtractCertsFromSignatureDatabase(database *signature.SignatureDatabase) []*x509.Certificate {
|
|
|
|
var result []*x509.Certificate
|
|
|
|
for _, k := range *database {
|
|
|
|
if isValidSignature(k.SignatureType) {
|
|
|
|
for _, k1 := range k.Signatures {
|
|
|
|
// Note the S at the end of the function, we are parsing multiple certs, not just one
|
|
|
|
certificates, err := x509.ParseCertificates(k1.Data)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
result = append(result, certificates...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2024-04-17 12:00:34 +00:00
|
|
|
// GetAllCerts returns a list of certs in the system
|
|
|
|
func GetAllCerts() (types.CertList, error) {
|
|
|
|
var certList types.CertList
|
|
|
|
pk, err := GetKeyDatabase("PK")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
kek, err := GetKeyDatabase("KEK")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
db, err := GetKeyDatabase("DB")
|
|
|
|
if err != nil {
|
|
|
|
return certList, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, k := range *pk {
|
|
|
|
if isValidSignature(k.SignatureType) {
|
|
|
|
for _, k1 := range k.Signatures {
|
|
|
|
// Note the S at the end of the function, we are parsing multiple certs, not just one
|
|
|
|
certificates, err := x509.ParseCertificates(k1.Data)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, cert := range certificates {
|
|
|
|
certList.PK = append(certList.PK, types.CertDetail{Owner: cert.Subject, Issuer: cert.Issuer})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, k := range *kek {
|
|
|
|
if isValidSignature(k.SignatureType) {
|
|
|
|
for _, k1 := range k.Signatures {
|
|
|
|
// Note the S at the end of the function, we are parsing multiple certs, not just one
|
|
|
|
certificates, err := x509.ParseCertificates(k1.Data)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, cert := range certificates {
|
|
|
|
certList.KEK = append(certList.KEK, types.CertDetail{Owner: cert.Subject, Issuer: cert.Issuer})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, k := range *db {
|
|
|
|
if isValidSignature(k.SignatureType) {
|
|
|
|
for _, k1 := range k.Signatures {
|
|
|
|
// Note the S at the end of the function, we are parsing multiple certs, not just one
|
|
|
|
certificates, err := x509.ParseCertificates(k1.Data)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, cert := range certificates {
|
|
|
|
certList.DB = append(certList.DB, types.CertDetail{Owner: cert.Subject, Issuer: cert.Issuer})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return certList, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// isValidSignature identifies a signature based as a DER-encoded X.509 certificate
|
|
|
|
func isValidSignature(sign util.EFIGUID) bool {
|
|
|
|
return sign == signature.CERT_X509_GUID
|
|
|
|
}
|