# C2PA SSL - Content Authentication Service

A Node.js wrapper for C2PA (Coalition for Content Provenance and Authenticity)
content signing using a Rust CLI backend.

## Architecture

This package uses a **CLI-based architecture** for optimal performance:

- **Rust CLI Binary**: Fast, native C2PA signing tool
- **Node.js Wrapper**: Simple interface for certificate management and CLI
  execution
- **Direct File Processing**: No HTTP overhead, direct file-to-file signing

## Platform Support

**Currently Supported:**

- ✅ macOS (darwin) - Native binary included
- ✅ Linux (x86_64) - Cross-compiled binary via Docker

**Not Yet Supported:**

- ❌ Windows (requires cross-compilation setup)

> **Note**: Linux support was added via Docker cross-compilation. The Linux
> binary is compatible with Firebase Functions and other Linux environments.

## Installation

```bash
npm install @binlebin/c2pa-ssl
```

## Environment Variables

```bash
# Required: Your private key content
export C2PA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
...your private key content...
-----END PRIVATE KEY-----"
```

## Usage

### Basic Usage

```javascript
const C2PAService = require("@binlebin/c2pa-ssl");

async function signContent() {
  const service = new C2PAService();

  try {
    // Initialize service (sets up certificates)
    await service.start();

    // Sign a file
    const result = await service.signFile(
      "input.jpg",
      "signed_output.jpg",
      {
        title: "My Signed Image",
        description: "Image signed with C2PA",
        author: "Your Name",
      },
    );

    console.log("Signing result:", result);
  } finally {
    // Clean up
    await service.stop();
  }
}
```

### Firebase Functions Integration

```javascript
import C2PAService = require("@binlebin/c2pa-ssl"); // eslint-disable-line

export const downloadMedia = onCall(async (request) => {
  const c2paService = new C2PAService();
  
  try {
    await c2paService.start();
    
    // Download and sign media
    const tempInput = `/tmp/input_${Date.now()}`;
    const tempOutput = `/tmp/signed_${Date.now()}`;
    
    // ... download logic ...
    
    await c2paService.signFile(tempInput, tempOutput, {
      title: mediaTitle,
      description: mediaDescription,
      author: 'visflow.ai'
    });
    
    // ... upload signed file ...
    
    return { success: true, c2paSigned: true };
  } finally {
    await c2paService.stop();
  }
});
```

## API Reference

### Class: C2PAService

#### Methods

##### `constructor()`

Creates a new C2PA service instance.

##### `async start()`

Initializes the service by setting up certificates. Must be called before
signing files.

**Throws:**

- Error if `C2PA_PRIVATE_KEY` environment variable is not set
- Error if platform is not supported
- Error if CLI binary is not found

##### `async stop()`

Cleans up temporary files and certificates.

##### `async signFile(inputPath, outputPath, metadata)`

Signs a file with C2PA authentication.

**Parameters:**

- `inputPath` (string): Path to input file
- `outputPath` (string): Path where signed file will be saved
- `metadata` (object): Optional metadata
  - `title` (string): Content title (default: "Signed Content")
  - `description` (string): Content description (default: "Content signed with
    C2PA")
  - `author` (string): Content author (default: "C2PA-CLI")

**Returns:** Promise resolving to:

```javascript
{
  success: boolean,
  message: string,
  stdout: string,
  stderr: string
}
```

## Supported File Formats

### Images

- JPEG/JPG
- PNG
- WebP
- TIFF
- BMP

### Videos

- MP4
- MOV (QuickTime)
- AVI
- WebM

### Audio

- MP3
- WAV
- M4A

## Performance

The CLI approach provides excellent performance:

### Image Signing

- **Small images** (11KB): ~151% size increase
- **Processing time**: < 1 second

### Video Signing

- **Medium videos** (1.2MB): ~1.4% size increase
- **Processing time**: < 2 seconds

## Testing

```bash
# Set up environment
export C2PA_PRIVATE_KEY="$(cat path/to/your/private.key)"

# Run tests
npm test
```

## Development

### Building the Rust CLI

**For macOS (native):**

```bash
cd rust-c2pa-service
cargo build --release
cp target/release/c2pa-cli ../c2pa-ssl/bin/
```

**For Linux (via Docker cross-compilation):**

```bash
cd rust-c2pa-service
docker build -f Dockerfile.linux -t c2pa-cli-linux .
docker create --name temp-container c2pa-cli-linux
docker cp temp-container:/output/c2pa-cli-linux .
docker rm temp-container
cp c2pa-cli-linux ../c2pa-ssl/bin/
```

### Adding Platform Support

To add support for other platforms:

1. **Windows**: Set up cross-compilation toolchain or Docker
2. **Update** `getBinaryPath()` method in `index.js`
3. **Add binary** to `package.json` files array

## Error Handling

Common errors and solutions:

### Platform Not Supported

```
Platform 'linux' is not currently supported
```

**Solution**: Use macOS or set up cross-compilation

### Missing Private Key

```
C2PA_PRIVATE_KEY environment variable is required
```

**Solution**: Set the environment variable with your private key content

### Binary Not Found

```
CLI binary not found at /path/to/binary
```

**Solution**: Ensure the binary exists and has execute permissions

## License

MIT License - see LICENSE file for details.
