mirror of
https://github.com/fleetdm/fleet
synced 2026-05-21 07:58:31 +00:00
Fixes #30458 Contributor docs PR: https://github.com/fleetdm/fleet/pull/30651 # Checklist for submitter - We will add changes file later. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] If database migrations are included, checked table schema to confirm autoupdate - For database migrations: - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [x] Added/updated automated tests - Did not do manual QA since the SCEP client I have doesn't support ECC. Will rely on next subtasks for manual QA. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced Host Identity SCEP (Simple Certificate Enrollment Protocol) support, enabling secure host identity certificate enrollment and management. * Added new API endpoints for Host Identity SCEP, including certificate issuance and retrieval. * Implemented MySQL-backed storage and management for host identity SCEP certificates and serials. * Added new database tables for storing host identity SCEP certificates and serial numbers. * Provided utilities for encoding certificates and keys, and handling ECDSA public keys. * **Bug Fixes** * None. * **Tests** * Added comprehensive integration and unit tests for Host Identity SCEP functionality, including certificate issuance, validation, and error scenarios. * **Chores** * Updated test utilities to support unique test names and new SCEP storage options. * Extended mock datastore and interfaces for new host identity certificate methods. * **Documentation** * Added comments and documentation for new SCEP-related interfaces, methods, and database schema changes. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
69 lines
2 KiB
Go
69 lines
2 KiB
Go
package mysql
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"strings"
|
|
|
|
"github.com/fleetdm/fleet/v4/pkg/certificate"
|
|
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
|
|
)
|
|
|
|
// CertStore implements storage tasks associated with MS-WSTEP messages in the MS-MDE2
|
|
// protocol. It is implemented by fleet.Datastore.
|
|
var _ microsoft_mdm.CertStore = (*Datastore)(nil)
|
|
|
|
// WSTEPStoreCertificate stores a certificate under the given name.
|
|
//
|
|
// If the provided certificate has empty crt.Subject.CommonName,
|
|
// then the hex sha256 of the crt.Raw is used as name.
|
|
func (ds *Datastore) WSTEPStoreCertificate(ctx context.Context, name string, crt *x509.Certificate) error {
|
|
if crt.Subject.CommonName == "" {
|
|
name = fmt.Sprintf("%x", sha256.Sum256(crt.Raw))
|
|
}
|
|
if !crt.SerialNumber.IsInt64() {
|
|
return errors.New("cannot represent serial number as int64")
|
|
}
|
|
certPEM := certificate.EncodeCertPEM(crt)
|
|
_, err := ds.writer(ctx).ExecContext(ctx, `
|
|
INSERT INTO wstep_certificates
|
|
(serial, name, not_valid_before, not_valid_after, certificate_pem)
|
|
VALUES
|
|
(?, ?, ?, ?, ?)`,
|
|
crt.SerialNumber.Int64(),
|
|
name,
|
|
crt.NotBefore,
|
|
crt.NotAfter,
|
|
certPEM,
|
|
)
|
|
return err
|
|
}
|
|
|
|
// WSTEPNewSerial allocates and returns a new (increasing) serial number.
|
|
func (ds *Datastore) WSTEPNewSerial(ctx context.Context) (*big.Int, error) {
|
|
result, err := ds.writer(ctx).ExecContext(ctx, `INSERT INTO wstep_serials () VALUES ();`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
lid, err := result.LastInsertId() // TODO: ok if sequential and not random?
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// TODO: check maxSerialNumber?
|
|
return big.NewInt(lid), nil
|
|
}
|
|
|
|
func (ds *Datastore) WSTEPAssociateCertHash(ctx context.Context, deviceUUID string, hash string) error {
|
|
_, err := ds.writer(ctx).ExecContext(ctx, `
|
|
INSERT INTO wstep_cert_auth_associations (id, sha256) VALUES (?, ?) AS new
|
|
ON DUPLICATE KEY
|
|
UPDATE sha256 = new.sha256;`,
|
|
deviceUUID,
|
|
strings.ToUpper(hash), // TODO: confirm if this is necessary
|
|
)
|
|
return err
|
|
}
|