package dkms

import (
	"bytes"
	"context"
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/binary"
	"encoding/pem"
	"fmt"
	"hash/crc32"
	"math/big"
	"os"
	"strings"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
	"github.com/golang/glog"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

const (
	// PKEYIDPKCS7 is the constant PKEY_ID_PKCS7 defined in https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	PKEYIDPKCS7 = byte(2)
	// magicNumber is the constant magic_number defined in https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	magicNumber = "~Module signature appended~\n"
)

// https://www.rfc-editor.org/rfc/rfc2315#section-9.1
//  SignedData ::= SEQUENCE {
//  version Version,
//  digestAlgorithms DigestAlgorithmIdentifiers,
//  contentInfo ContentInfo,
//  certificates
//     [0] IMPLICIT ExtendedCertificatesAndCertificates
//       OPTIONAL,
//  crls
//    [1] IMPLICIT CertificateRevocationLists OPTIONAL,
//  signerInfos SignerInfos }

type signedData struct {
	Version                    int
	DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
	ContentInfo                contentInfo
	SignerInfos                []signerInfo `asn1:"set"`
}

// https://www.rfc-editor.org/rfc/rfc2315#section-7
// ContentInfo ::= SEQUENCE {
//
//	 contentType ContentType,
//	 content  // NOTE: not needed for detached signature
//	 [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
//
//	ContentType ::= OBJECT IDENTIFIER
type contentInfo struct {
	ContentType asn1.ObjectIdentifier
}

// https://www.rfc-editor.org/rfc/rfc2315#section-9.2
// SignerInfo ::= SEQUENCE {
//
//	version Version,
//	issuerAndSerialNumber IssuerAndSerialNumber,
//	digestAlgorithm DigestAlgorithmIdentifier,
//	authenticatedAttributes  // NOTE: not used in Linux kernel module signature
//	  [0] IMPLICIT Attributes OPTIONAL,
//	digestEncryptionAlgorithm
//	  DigestEncryptionAlgorithmIdentifier,
//	encryptedDigest EncryptedDigest,
//	unauthenticatedAttributes // NOTE: not used in Linux kernel module signature
//	  [1] IMPLICIT Attributes OPTIONAL }
//
// EncryptedDigest ::= OCTET STRING
type signerInfo struct {
	Version                   int
	IssuerAndSerialNumber     issuerAndSerialNumber
	DigestAlgorithm           pkix.AlgorithmIdentifier
	DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
	EncryptedDigest           []byte
}

// https://www.rfc-editor.org/rfc/rfc2315#section-6.7
// IssuerAndSerialNumber ::= SEQUENCE {
//
//	issuer Name,
//	serialNumber CertificateSerialNumber }
type issuerAndSerialNumber struct {
	Issuer       asn1.RawValue
	SerialNumber *big.Int
}

type pkcs7Blob struct {
	Oid        asn1.ObjectIdentifier
	SignedData signedData `asn1:"tag:0,explicit"`
}

type digestAlgorithm struct {
	identifier asn1.ObjectIdentifier
	hash       crypto.Hash
}

// ModuleSigner is an interface for signing kernel modules.
type ModuleSigner interface {
	// Sign generates a digital signature for the given module bytes.
	Sign(moduleBytes []byte, hash crypto.Hash) ([]byte, error)
	// retrieveDigestEncryptionAlgorithm returns the algorithm identifier used for
	// encrypting the digest (e.g., RSA).
	retrieveDigestEncryptionAlgorithm() (*pkix.AlgorithmIdentifier, error)
}

// KmsSigner implements the ModuleSigner interface using Google Cloud KMS for signing operations.
type KmsSigner struct {
	ctx     context.Context
	client  *kms.KeyManagementClient
	keyName string
}

// LocalSigner implements the ModuleSigner interface using a local private key for signing.
type LocalSigner struct {
	key crypto.PrivateKey
}

var (
	oidData          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
	oidRsaEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
	oidSignedData    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}

	digests = map[string]digestAlgorithm{
		"sha256": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1},
			hash:       crypto.SHA256,
		},
		"sha384": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2},
			hash:       crypto.SHA384,
		},
		"sha512": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3},
			hash:       crypto.SHA512,
		},
		"sha3-256": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 8},
			hash:       crypto.SHA3_256,
		},
		"sha3-384": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 9},
			hash:       crypto.SHA3_384,
		},
		"sha3-512": {
			identifier: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 10},
			hash:       crypto.SHA3_512,
		},
	}
)

func newKmsSigner(ctx context.Context, kmsKey string) (*KmsSigner, error) {
	client, err := kms.NewKeyManagementClient(ctx)
	if err != nil {
		return nil, err
	}
	return &KmsSigner{ctx: ctx, client: client, keyName: kmsKey}, nil
}

func newLocalSigner(keyPath string) (*LocalSigner, error) {
	keyBytes, err := os.ReadFile(keyPath)
	if err != nil {
		return nil, fmt.Errorf("failed to read private key file (%s): %v", keyPath, err)
	}
	key, err := parsePrivateKey(keyBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve private key: %v", err)
	}
	return &LocalSigner{key: key}, nil

}

func (l *LocalSigner) Sign(moduleBytes []byte, hash crypto.Hash) ([]byte, error) {
	// Retrieve the crypto signer if it is implemented for the private key
	signer, ok := l.key.(crypto.Signer)
	if !ok {
		return nil, fmt.Errorf("could not retrieve crypto signer for key type: %T", l.key)
	}
	h := hash.New()
	h.Write(moduleBytes)
	moduleDigest := h.Sum(nil)
	signature, err := signer.Sign(rand.Reader, moduleDigest, hash)
	if err != nil {
		return nil, fmt.Errorf("failed to sign the module digest: %v", err)
	}
	return signature, nil
}

func (l *LocalSigner) retrieveDigestEncryptionAlgorithm() (*pkix.AlgorithmIdentifier, error) {
	switch l.key.(type) {
	case *rsa.PrivateKey:
		return &pkix.AlgorithmIdentifier{Algorithm: oidRsaEncryption, Parameters: asn1.NullRawValue}, nil
	default:
		return nil, fmt.Errorf("unsupported digest encryption algorithm: %T", l.key)
	}
}

func (k *KmsSigner) Sign(moduleBytes []byte, hash crypto.Hash) ([]byte, error) {
	h := hash.New()
	h.Write(moduleBytes)
	moduleDigest := h.Sum(nil)
	kmsDigest, err := k.retrieveDigestAlg(hash, moduleDigest)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve KMS digest algorithm: %v", err)
	}

	// Compute digest's CRC32C
	t := crc32.MakeTable(crc32.Castagnoli)
	digestCRC32C := crc32.Checksum(moduleDigest, t)

	req := &kmspb.AsymmetricSignRequest{
		Name:         k.keyName,
		Digest:       kmsDigest,
		DigestCrc32C: wrapperspb.Int64(int64(digestCRC32C)),
	}

	result, err := k.client.AsymmetricSign(k.ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to generate signature using KMS: %v", err)
	}

	// Verify integrity of the result
	if !result.VerifiedDigestCrc32C {
		return nil, fmt.Errorf("AsymmetricSignError: digest corrupted in transit")
	}
	if result.Name != req.Name {
		return nil, fmt.Errorf("AsymmetricSignError: mismatched key name in the response")
	}
	if int64(crc32.Checksum(result.Signature, t)) != result.SignatureCrc32C.Value {
		return nil, fmt.Errorf("AsymmetricSignError: response corrupted in transit")
	}
	return result.Signature, nil
}

func (k *KmsSigner) retrieveDigestEncryptionAlgorithm() (*pkix.AlgorithmIdentifier, error) {
	req := &kmspb.GetCryptoKeyVersionRequest{
		Name: k.keyName,
	}
	keyVersion, err := k.client.GetCryptoKeyVersion(k.ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to get key version: %v", err)
	}
	// Verify that key encryption is supported
	encryptAlg := keyVersion.GetAlgorithm().String()
	if strings.HasPrefix(encryptAlg, "RSA_") {
		return &pkix.AlgorithmIdentifier{Algorithm: oidRsaEncryption, Parameters: asn1.NullRawValue}, nil
	}
	return nil, fmt.Errorf("unsupported digest encryption algorithm: %v", encryptAlg)
}

func (k *KmsSigner) retrieveDigestAlg(hash crypto.Hash, moduleDigest []byte) (*kmspb.Digest, error) {
	var digest *kmspb.Digest
	switch hash {
	case crypto.SHA256:
		digest = &kmspb.Digest{
			Digest: &kmspb.Digest_Sha256{
				Sha256: moduleDigest,
			},
		}
	case crypto.SHA384:
		digest = &kmspb.Digest{
			Digest: &kmspb.Digest_Sha384{
				Sha384: moduleDigest,
			},
		}
	case crypto.SHA512:
		digest = &kmspb.Digest{
			Digest: &kmspb.Digest_Sha512{
				Sha512: moduleDigest,
			},
		}
	default:
		return nil, fmt.Errorf("unsupported kms digest algorithm: %s", hash.String())
	}
	return digest, nil
}

// SignModules signs a list of compiled kernel modules using the provided ModuleSigner.
// Currently, only rsa private keys are supported. It creates a pkcs7 signature
// and appends it to the end of a compiled kernel module.
//
// The ModuleSigner handles the specific signing method (e.g., local key or Cloud KMS)
// This is an implementation of https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
func SignModules(modules []Module, certificatePath, hash string, signer ModuleSigner) error {
	certBytes, err := os.ReadFile(certificatePath)
	if err != nil {
		return fmt.Errorf("failed to read certificate key file (%s): %v", certificatePath, err)
	}
	cert, err := x509.ParseCertificate(certBytes)
	if err != nil {
		return fmt.Errorf("failed to retrieve certificate (%s): %v", certificatePath, err)
	}

	digest, ok := digests[strings.ToLower(hash)]
	if !ok {
		return fmt.Errorf("unsupported digest algorithm: %s", hash)
	}

	encryptAlg, err := signer.retrieveDigestEncryptionAlgorithm()
	if err != nil {
		return fmt.Errorf("failed to retrieve digest encryption algorithm: %v", err)
	}

	var signedModules, skippedModules []string
	for _, module := range modules {
		moduleName := module.BuiltName
		modulePath := module.BuiltPath()
		glog.Infof("signing module %s", moduleName)
		moduleBytes, err := os.ReadFile(modulePath)
		if err != nil {
			skippedModules = append(skippedModules, moduleName)
			glog.Errorf("failed to read module file (%s) [skipping]: %v", moduleName, err)
			continue
		}
		signedBytes, err := signModule(signer, moduleBytes, digest, cert, encryptAlg)
		if err != nil {
			skippedModules = append(skippedModules, moduleName)
			glog.Errorf("failed to sign module (%s) [skipping]: %v", moduleName, err)
			continue
		}
		if err := os.WriteFile(modulePath, signedBytes, 0644); err != nil {
			skippedModules = append(skippedModules, moduleName)
			glog.Errorf("failed to write signed module (%s) to file (%s) [skipping]: %v", moduleName, modulePath, err)
			continue
		}
		signedModules = append(signedModules, moduleName)
		glog.Infof("successfully signed module '%s'", moduleName)
	}

	if len(signedModules) > 0 {
		glog.Infof("Successfully signed module(s): %v", signedModules)
	}
	if len(skippedModules) > 0 {
		glog.Errorf("Failed to sign module(s): %v", skippedModules)
	}

	return nil
}

func parsePrivateKey(contents []byte) (crypto.PrivateKey, error) {
	// Retrieve pem encoded block.
	block, _ := pem.Decode(contents)
	if block == nil {
		return nil, fmt.Errorf("failed to decode pem-formatted key or invalid key type")
	}

	var privateKey crypto.PrivateKey
	var err error
	switch block.Type {
	case "RSA PRIVATE KEY":
		privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return nil, fmt.Errorf("failed to parse rsa private key: %v", err)
		}
	case "PRIVATE KEY":
		key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
		if err != nil {
			return nil, fmt.Errorf("failed to parse private key: %v", err)
		}
		switch k := key.(type) {
		case *rsa.PrivateKey:
			privateKey = k
		default:
			return nil, fmt.Errorf("unsupported key type: %T", key)
		}
	default:
		return nil, fmt.Errorf("unsupported block type: %s", block.Type)
	}
	return privateKey, nil
}

func signModule(signer ModuleSigner, moduleBytes []byte, digest digestAlgorithm, cert *x509.Certificate, encryptAlg *pkix.AlgorithmIdentifier) ([]byte, error) {
	signature, err := signer.Sign(moduleBytes, digest.hash)
	if err != nil {
		return nil, fmt.Errorf("failed to generate module signature: %v", err)
	}

	digestAlg := &pkix.AlgorithmIdentifier{Algorithm: digest.identifier, Parameters: asn1.NullRawValue}
	sinfo := signerInfo{
		Version: 1,
		IssuerAndSerialNumber: issuerAndSerialNumber{
			Issuer:       asn1.RawValue{FullBytes: cert.RawIssuer},
			SerialNumber: cert.SerialNumber,
		},
		DigestAlgorithm:           *digestAlg,
		DigestEncryptionAlgorithm: *encryptAlg,
		EncryptedDigest:           signature,
	}

	blob := pkcs7Blob{
		Oid: oidSignedData,
		SignedData: signedData{
			Version:                    1,
			DigestAlgorithmIdentifiers: []pkix.AlgorithmIdentifier{*digestAlg},
			ContentInfo:                contentInfo{ContentType: oidData},
			SignerInfos:                []signerInfo{sinfo},
		},
	}
	marshalled, err := asn1.Marshal(blob)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal signed module pkcs7 blob: %v", err)
	}

	return appendSignature(marshalled, moduleBytes)
}

// appendSignature appends a raw PKCS#7 signature to the end of a given kernel module.
func appendSignature(signature []byte, moduleBytes []byte) ([]byte, error) {
	var buf bytes.Buffer
	// Write bytes of kernel module.
	if _, err := buf.Write(moduleBytes); err != nil {
		return nil, fmt.Errorf("failed to write module bytes to buffer: %v", err)
	}
	// Copy bytes of module signature.
	sigSize, err := buf.Write(signature)
	if err != nil {
		return nil, fmt.Errorf("failed to write signature to buffer: %v", err)
	}
	// Append the marker and the PKCS#7 message.
	// signatureInfo is the struct module_signature defined in
	// https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	signatureInfo := [12]byte{}
	// signatureInfo[2] is the id_type of struct module_signature
	signatureInfo[2] = PKEYIDPKCS7
	// signatureInfo[8:12] is the sig_len of struct module_signature.
	// Using BigEndian as the sig_len should be in network byte order.
	binary.BigEndian.PutUint32(signatureInfo[8:12], uint32(sigSize))
	if _, err := buf.Write(signatureInfo[:]); err != nil {
		return nil, fmt.Errorf("failed to write module signature struct to buffer: %v", err)
	}

	if _, err := buf.WriteString(magicNumber); err != nil {
		return nil, fmt.Errorf("failed to write magic number to buffer: %v", err)
	}

	return buf.Bytes(), nil
}
