crx3

package module
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2025 License: Apache-2.0 Imports: 22 Imported by: 4

README

go-crx3

Coverage Status Documentation Go Report Card Actions

Provides a sets of tools packing, unpacking, zip, unzip, download, gen id, etc...

Table of contents

Installation
go get -u github.com/mediabuyerbot/go-crx3/crx3
go install github.com/mediabuyerbot/go-crx3/crx3@latest

OR download the binary from here

https://github.com/mmadfox/go-crx3/releases
Dev commands
$ make proto 
$ make test/cover
Examples
Pack
Pack a zip file or unzipped directory into a crx extension
import crx3 "github.com/mediabuyerbot/go-crx3"

if err := crx3.Extension("/path/to/file.zip").Pack(nil); err != nil {
    panic(err)
}
import crx3 "github.com/mediabuyerbot/go-crx3"

pk, err := crx3.LoadPrivateKey("/path/to/key.pem")
if err != nil { 
    panic(err) 
}
if err := crx3.Extension("/path/to/file.zip").Pack(pk); err != nil {
    panic(err)
}
import crx3 "github.com/mediabuyerbot/go-crx3"

pk, err := crx3.LoadPrivateKey("/path/to/key.pem")
if err != nil { 
    panic(err) 
}
if err := crx3.Extension("/path/to/file.zip").PackTo("/path/to/ext.crx", pk); err != nil {
    panic(err)
}
$ crx3 pack /path/to/file.zip 
$ crx3 pack /path/to/file.zip -p /path/to/key.pem 
$ crx3 pack /path/to/file.zip -p /path/to/key.pem -o /path/to/ext.crx 
Unpack
Unpack chrome extension into current directory
import crx3 "github.com/mediabuyerbot/go-crx3"

if err := crx3.Extension("/path/to/ext.crx").Unpack(); err != nil {
   panic(err)
}
$ crx3 unpack /path/to/ext.crx 
Base64
Encode an extension file to a base64 string
import crx3 "github.com/mediabuyerbot/go-crx3"
import "fmt"

b, err := crx3.Extension("/path/to/ext.crx").Base64()
if err != nil {
   panic(err)
}
fmt.Println(string(b))
$ crx3 base64 /path/to/ext.crx [-o /path/to/file] 
Download
Download a chrome extension from the web store
import crx3 "github.com/mediabuyerbot/go-crx3"

extensionID := "blipmdconlkpinefehnmjammfjpmpbjk"
filepath := "/path/to/ext.crx"
if err := crx3.DownloadFromWebStore(extensionID,filepath); err != nil {
    panic(err)
}
$ crx3 download blipmdconlkpinefehnmjammfjpmpbjk [-o /custom/path]
$ crx3 download https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk
Zip
Zip add an unpacked extension to the archive
import crx3 "github.com/mediabuyerbot/go-crx3"

if err := crx3.Extension("/path/to/unpacked").Zip(); err != nil {
    panic(err)
}
$ crx3 zip /path/to/unpacked [-o /custom/path] 
Unzip
Unzip an extension to the current directory
import crx3 "github.com/mediabuyerbot/go-crx3"

if err := crx3.Extension("/path/to/ext.zip").Unzip(); err != nil {
    panic(err)
}
$ crx3 unzip /path/to/ext.zip [-o /custom/path] 
Gen ID
Generate extension id (like dgmchnekcpklnjppdmmjlgpmpohmpmgp)
import crx3 "github.com/mediabuyerbot/go-crx3"

id, err := crx3.Extension("/path/to/ext.crx").ID()
if err != nil {
    panic(err)
}
$ crx3 id /path/to/ext.crx 
IsDir, IsZip, IsCRX3
import crx3 "github.com/mediabuyerbot/go-crx3"

crx3.Extension("/path/to/ext.zip").IsZip()
crx3.Extension("/path/to/ext").IsDir()
crx3.Extension("/path/to/ext.crx").IsCRX3()
NewPrivateKey, LoadPrivateKey, SavePrivateKey
import crx3 "github.com/mediabuyerbot/go-crx3"

pk, err := crx3.NewPrivateKey()
if err != nil {
    panic(err)
}
if err := crx3.SavePrivateKey("/path/to/key.pem", pk); err != nil {
    panic(err)
}
pk, err = crx3.LoadPrivateKey("/path/to/key.pem")
Keygen
$ crx3 keygen /path/to/key.pem 

License

go-crx3 is released under the Apache 2.0 license. See LICENSE.txt

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnknownFileExtension  = errors.New("crx3: unknown file extension")
	ErrUnsupportedFileFormat = errors.New("crx3: unsupported file format")
	ErrExtensionNotSpecified = errors.New("crx3: extension id not specified")
	ErrPathNotFound          = errors.New("crx3: filepath not found")
	ErrPrivateKeyNotFound    = errors.New("crx3: private key not found")
	ErrInvalidReader         = errors.New("crx3: invalid reader")
)

Functions

func Base64 added in v1.3.0

func Base64(filename string) (b []byte, err error)

Base64 encodes an extension file to a base64 string. It returns a bytes and an error encountered while encodes, if any.

func CopyFile added in v1.4.0

func CopyFile(src, dst string) (int64, error)

CopyFile copies the contents of the source file 'src' to the destination file 'dst'. It returns the number of bytes copied and any encountered error. If the source file does not exist, is not a regular file, or other errors occur during the copy, it returns an error with a descriptive message.

func DownloadFromWebStore

func DownloadFromWebStore(extensionID string, filename string) error

DownloadFromWebStore downloads a Chrome extension from the web store. ExtensionID can be an identifier or an url.

func ID added in v1.2.0

func ID(filename string) (id string, err error)

ID returns the extension ID extracted from a CRX (Chrome Extension) file specified by 'filename'. It checks if the file is in the CRX format, reads its header and signed data, and then converts the CRX ID into a string representation

func IDFromPubKey added in v1.5.1

func IDFromPubKey(pubKey []byte) (string, error)

IDFromPubKey generates the Chrome Extension ID from a public key. It handles PEM formatting, base64 decoding, and SHA-256 hashing to produce the ID. Returns the ID or an error if the key processing fails.

func LoadPrivateKey

func LoadPrivateKey(filename string) (*rsa.PrivateKey, error)

LoadPrivateKey loads the RSA private key from the specified 'filename' into memory. It returns the loaded private key or an error if the key cannot be loaded.

func NewPrivateKey

func NewPrivateKey() (*rsa.PrivateKey, error)

NewPrivateKey returns a new RSA private key with a bit size of 4096.

func Pack

func Pack(src string, dst string, pk *rsa.PrivateKey) (err error)

Pack packs a zip file or unzipped directory into a crx extension. It takes the source 'src' (zip file or directory), target 'dst' CRX file path, and a private key 'pk' (optional). If 'pk' is nil, it generates a new private key. It creates a CRX extension from the source and writes it to the destination.

func PackZipToCRX added in v1.5.0

func PackZipToCRX(zip io.ReadSeeker, w io.Writer, pk *rsa.PrivateKey) error

PackZipToCRX reads a ZIP archive from the provided Reader, signs it using the provided RSA private key, and writes the signed CRX file to the provided Writer. This function is essential for producing production-ready CRX files that require digital signatures to be installed in browsers. The function will return an error if any issues occur during the zip reading, signing, or CRX writing processes.

func PrivateKeyToPEM added in v1.5.0

func PrivateKeyToPEM(key *rsa.PrivateKey) []byte

PublicKeyToPEM converts the provided RSA public key to a PEM-encoded byte slice.

func ReadZipFile added in v1.5.0

func ReadZipFile(filename string) (*bytes.Reader, error)

ReadZipFile opens and reads the contents of a zip file specified by 'filename'. It can handle both direct paths to zip files or directories. If 'filename' is a directory, the function zips its contents into a buffer and returns a reader for that buffer. If 'filename' is a zip file, it reads the file into a buffer and returns a reader for it. The function returns a *bytes.Reader to allow random access reads, which is particularly useful for large files. It returns an error if the file cannot be opened, read, or if the path does not correspond to a zip file or directory.

func SavePrivateKey

func SavePrivateKey(filename string, key *rsa.PrivateKey) error

SavePrivateKey saves the provided 'key' private key to the specified 'filename'. If 'key' is nil, it generates a new private key and saves it to the file.

func SetDefaultKeySize added in v1.5.0

func SetDefaultKeySize(size int)

SetDefaultKeySize sets the global default key size for RSA key generation. It accepts key sizes of 2048, 3072, or 4096 bits. If a size outside these specified options is passed, the function panics to prevent the use of an unsupported key size, which could lead to security vulnerabilities. This strict enforcement helps ensure that only strong, widely accepted key sizes are used throughout the application.

Usage:

SetDefaultKeySize(2048)  // sets the default key size to 2048 bits
SetDefaultKeySize(4096)  // sets the default key size to 4096 bits

Valid key sizes are:

  • 2048 bits
  • 3072 bits
  • 4096 bits

Panics:

This function will panic if any key size other than the above mentioned
valid sizes is attempted to be set. This is a deliberate design choice
to catch incorrect key size settings during the development phase.

func SetWebStoreURL added in v1.3.0

func SetWebStoreURL(u string)

SetWebStoreURL sets the web store url to download extensions.

func Unpack

func Unpack(filename string) error

Unpack unpacks a CRX (Chrome Extension) file specified by 'filename' to its original contents. It checks if the file is in the CRX format, reads its header and signed data, and then extracts and decompresses the original contents. The unpacked contents are placed in a directory with the same name as the original file (without the '.crx' extension).

func UnpackTo added in v1.4.0

func UnpackTo(filename string, dirname string) error

UnpackTo unpacks a CRX (Chrome Extension) file specified by 'filename' to the directory 'dirname'. If 'dirname' does not exist, it creates the directory before unpacking.

func Unzip

func Unzip(r io.ReaderAt, size int64, unpacked string) error

Unzip extracts all files and directories from the provided ZIP archive. It takes an io.ReaderAt 'r', the size 'size' of the ZIP archive, and the target directory 'unpacked' for extraction. It iterates through the archive, creating directories and writing files as necessary.

func UnzipTo added in v1.4.0

func UnzipTo(basepath string, filename string) error

UnzipTo extracts the contents of a ZIP archive specified by 'filename' to the 'basepath' directory. It opens the ZIP file, creates the necessary directory structure, and extracts all files.

func WritePrivateKey added in v1.5.0

func WritePrivateKey(w io.Writer, key *rsa.PrivateKey) error

WritePrivateKey writes the RSA private key to the provided io.Writer in the PEM format. The function expects a non-nil *rsa.PrivateKey. If the key is nil, it returns an ErrPrivateKeyNotFound error. This function handles the marshalling of the private key into PKCS#8 format and then encodes it into PEM format before writing.

Parameters:

w    : An io.Writer to which the PEM encoded private key will be written.
key  : A non-nil *rsa.PrivateKey that will be marshalled and written.

Returns:

An error if the private key is nil, if there is a marshalling error, or if writing
to the io.Writer fails. The error includes a descriptive message to aid in debugging.

Usage example:

file, err := os.Create("private_key.pem")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
    log.Fatal(err)
}

if err := WritePrivateKey(file, privKey); err != nil {
    log.Printf("Failed to write private key: %v", err)
}

Note:

This function does not close the io.Writer; the caller is responsible for managing
the writer's lifecycle, including opening and closing it.

func Zip

func Zip(dst io.Writer, dirname string) error

Zip creates a *.zip archive and adds all files from the specified directory to it.

func ZipTo added in v1.4.0

func ZipTo(filename string, dirname string) error

ZipTo creates a ZIP archive with the specified filename and adds all files from the given directory to it.

Types

type Extension

type Extension string

Extension represents an extension for google chrome.

func (Extension) Base64 added in v1.3.0

func (e Extension) Base64() ([]byte, error)

Base64 encodes an extension file to a base64 string.

func (Extension) ID added in v1.2.0

func (e Extension) ID() (string, error)

ID calculates the Chrome Extension ID for the Extension instance. It supports directories, ZIP archives, and CRX3 files. If the extension is unpacked, contained in a ZIP archive, or is a CRX3 file with a specified key in its manifest, the ID is generated from this key. The function returns an error if the extension is empty, the file cannot be read, the key is not found, or the file format is unsupported.

func (Extension) IsCRX3 added in v1.1.0

func (e Extension) IsCRX3() bool

IsCRX3 reports whether extension describes a crx file.

func (Extension) IsDir added in v1.1.0

func (e Extension) IsDir() bool

IsDir reports whether extension describes a directory.

func (Extension) IsEmpty added in v1.4.0

func (e Extension) IsEmpty() bool

IsEmpty checks if the extension is empty.

func (Extension) IsZip added in v1.1.0

func (e Extension) IsZip() bool

IsZip reports whether extension describes a zip-archive.

func (Extension) Pack

func (e Extension) Pack(pk *rsa.PrivateKey) error

Pack packs zip file or an unpacked directory into a CRX3 file.

func (Extension) PackTo

func (e Extension) PackTo(dst string, pk *rsa.PrivateKey) error

PackTo packs zip file or an unpacked directory into a CRX3 file.

func (Extension) String

func (e Extension) String() string

String returns a string representation.

func (Extension) Unpack

func (e Extension) Unpack() error

Unpack unpacks the CRX3 extension into a directory.

func (Extension) Unzip

func (e Extension) Unzip() error

Unzip extracts all files from the archive.

func (Extension) WriteTo added in v1.5.0

func (e Extension) WriteTo(w io.Writer, pk *rsa.PrivateKey) error

WriteTo packs the contents of the Extension into a CRX file and writes it to the provided io.Writer. This method requires a non-nil *rsa.PrivateKey to sign the CRX package. The Extension must not be empty, and its associated zip file must be readable and correctly formatted.

Parameters:

w  - The io.Writer where the CRX file will be written.
pk - The RSA private key used for signing the CRX file.

Returns:

An error if the Extension is empty, if the private key is nil, if there are issues reading the
zip file associated with the Extension, or if there is a failure during the packing process.
Errors are wrapped with context to provide more details about the failure.

Usage example:

ext := Extension("path/to/your/extension/folder") // OR zip file
pk, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
    log.Fatalf("Failed to generate private key: %v", err)
}

var buf bytes.Buffer
if err := ext.WriteTo(&buf, pk); err != nil {
    log.Printf("Failed to write CRX: %v", err)
} else {
    // Use buf to save CRX to a file or further processing
}

func (Extension) Zip

func (e Extension) Zip() error

Zip creates a *.zip archive and adds all the files to it.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL