Skip to content

Commit

Permalink
Merge pull request #6 from MGTheTrain/feature/pkcs11-integration
Browse files Browse the repository at this point in the history
Feature/pkcs11 integration
  • Loading branch information
MGTheTrain authored Nov 16, 2024
2 parents ac8439f + 2105e8d commit 6c115fa
Show file tree
Hide file tree
Showing 23 changed files with 1,475 additions and 149 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"image": "mcr.microsoft.com/vscode/devcontainers/go:1.21",
// Features to add to the dev container. More info: https://containers.dev/features
"features": {},
"postCreateCommand": "apt-get update && apt-get install -y opensc softhsm",
"postCreateCommand": "apt-get update && apt-get install -y openssl opensc softhsm libssl-dev libengine-pkcs11-openssl",
"remoteUser": "root"
}
13 changes: 10 additions & 3 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ jobs:
run: ./run-test.sh -u
working-directory: ./scripts

# - name: Run Integration tests
# run: sudo ./run-test.sh -i
# working-directory: ./scripts
# Spin up integration environment (docker-compose or public hyper scaler infrastructure)

- name: Install apt dependencies for integration test
run: |
sudo apt-get update
sudo apt-get install -y openssl opensc softhsm libssl-dev libengine-pkcs11-openssl
- name: Run Integration tests
run: sudo ./run-test.sh -i
working-directory: ./scripts

# Run static code analysis on source code
# Run vulnerability scanner and generate SBOMs on third part dependencies
Expand Down
13 changes: 10 additions & 3 deletions .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ jobs:
run: ./run-test.sh -u
working-directory: ./scripts

# - name: Run Integration tests
# run: ./run-test.sh -i
# working-directory: ./scripts
# Spin up integration environment (docker-compose or public hyper scaler infrastructure)

- name: Install apt dependencies for integration test
run: |
sudo apt-get update
sudo apt-get install -y openssl opensc softhsm libssl-dev libengine-pkcs11-openssl
- name: Run Integration tests
run: sudo ./run-test.sh -i
working-directory: ./scripts

# Run static code analysis on source code
# Run vulnerability scanner and generate SBOMs on third part dependencies
Expand Down
13 changes: 10 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ jobs:
run: ./run-test.sh -u
working-directory: ./scripts

# - name: Run Integration tests
# run: ./run-test.sh -i
# working-directory: ./scripts
# Spin up integration environment (docker-compose or public hyper scaler infrastructure)

- name: Install apt dependencies for integration test
run: |
sudo apt-get update
sudo apt-get install -y openssl opensc softhsm libssl-dev libengine-pkcs11-openssl
- name: Run Integration tests
run: sudo ./run-test.sh -i
working-directory: ./scripts

# Run static code analysis on source code
# Run vulnerability scanner and generate SBOMs on third part dependencies
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- **Asymmetric encryption and decryption**: Supported RSA and other asymmetric encryption algorithms for data protection.
- **Symmetric encryption**: Supported symmetric key encryption (e.g. AES) for data protection.
- **Hashing and signature verification**: Supported hashing algorithms (e.g. SHA-256, SHA-512) and verified signatures using asymmetric keys (RSA, ECDSA, etc.).
**Signature creation and verification:** Support for hashing algorithms (e.g. SHA-256, SHA-512) to create digital signatures, and the ability to verify these signatures using asymmetric keys (RSA, ECDSA).
- **Scalable and maintainable project structure**: Referred to the [project-layout GitHub repo](https://github.com/golang-standards/project-layout) and adopted Domain-Driven Design to create a **modular, flexible and maintainable** project structure with a focus on the **domain at its core**
- **CI workflows for quality checks**: Set up continuous integration workflows with GitHub Actions for automated linting, functional testing, building and pushing artifacts.
- **PKCS#11 integration**: Enabled key management and cryptographic operations (such as RSA-PKCS encryption/decryption and RSA-PSS or ECDSA signing/verification) through PKCS#11 interfaces supporting both FIPS-compliant hardware and software environments.

## [0.1.0] - TBD-TBD-TBD

Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ RESTful Web API for managing cryptographic keys and securing data at rest (metad

## References

TBD
- [OpenSSL with libp11 for Signing, Verifying and Encrypting, Decrypting](https://docs.yubico.com/hardware/yubihsm-2/hsm-2-user-guide/hsm2-openssl-libp11.html#rsa-pkcs)
- [pkcs11-tool usage](https://docs.nitrokey.com/nethsm/pkcs11-tool#id1)

## Features

Expand All @@ -22,8 +23,8 @@ TBD
- [ ] **Provide RESTful API for cryptographic operations**: Expose endpoints for managing cryptographic material and securing data (files, metadata) at rest.
- [x] **Asymmetric encryption and decryption**: Support RSA and other asymmetric encryption algorithms for data protection.
- [x] **Symmetric encryption**: Support for symmetric key encryption (e.g. AES) for data protection.
- [x] **Hashing and signature verification**: Support hashing algorithms (e.g. SHA-256, SHA-512) and verify signatures using asymmetric keys (RSA, ECDSA, etc.).
- [ ] **PKCS#11 integration**: Enable key management in FIPS-compliant hardware or software.
- [x] **Signature creation and verification:** Support for hashing algorithms (e.g. SHA-256, SHA-512) to create digital signatures, and the ability to verify these signatures using asymmetric keys (RSA, ECDSA).
- [x] **PKCS#11 integration**: Enable key management and cryptographic operations (such as RSA-PKCS encryption/decryption and RSA-PSS or ECDSA signing/verification) through PKCS#11 interfaces supporting both FIPS-compliant hardware and software environments.
- [ ] **Manage cryptographic material**: Enable management of private/public key pairs and symmetric keys (generation, import/export, rotation, etc.).
- [ ] **Key management lifecycle**: Implement key lifecycle management (generation, rotation, revocation, expiration).
- [ ] **Secure file storage integration**: Provide mechanisms to securely store encrypted files in BLOB storage (e.g. AWS S3, Azure Blob Storage, Google Cloud Storage).
Expand Down Expand Up @@ -52,7 +53,7 @@ TBD

```sh
apt-get update
apt-get install -y opensc softhsm
apt-get install -y openssl opensc softhsm libssl-dev libengine-pkcs11-openssl
```

### Formatting and linting
Expand Down Expand Up @@ -85,14 +86,14 @@ or
make run-unit-tests
```

**TBD** To run `integration` tests on Unix systems either execute
To run `integration` tests on Unix systems either execute

```sh
cd scripts
./run-test.sh -i
```

**TBD** or
or

```sh
make run-integration-tests
Expand Down
89 changes: 79 additions & 10 deletions cmd/crypto-vault-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@

## Table of Contents

+ [Summary](#summary)
+ [Getting started](#getting-started)
- [Summary](#summary)
- [Getting Started](#getting-started)
- [Encryption and Decryption](#encryption-and-decryption)
- [AES Example](#aes-example)
- [RSA Example](#rsa-example)
- [PKCS#11 Encryption and Decryption](#pkcs11-encryption-and-decryption)
- [Signing and Verifying Signatures](#signing-and-verifying-signatures)
- [ECDSA Example](#ecdsa-example)
- [PKCS#11 Signing and Verifying](#pkcs11-signing-and-verifying)
- [PKCS#11 key management operations](#pkcs11-key-management-operations)

## Summary

`crypto-vault-cli` is a command-line tool for file encryption and decryption using AES, RSA and EC algorithms. It provides an easy interface to securely encrypt and decrypt files using symmetric (AES) and asymmetric (RSA, EC) cryptography.

## Getting Started

**NOTE**: Keys will be generated internally during the encryption or signature generation operations.
### Encryption and Decryption

### Encryption/Decryption
#### AES example

**AES example**
*NOTE:* Keys will be generated internally during the encryption operations.

```sh
uuid=$(cat /proc/sys/kernel/random/uuid)
Expand All @@ -25,7 +33,9 @@ go run crypto-vault-cli.go encrypt-aes --input data/input.txt --output data/${uu
go run crypto-vault-cli.go decrypt-aes --input data/${uuid}-output.enc --output data/${uuid}-decrypted.txt --symmetricKey <your generated symmetric key from previous encryption operation>
```

**RSA Example**
#### RSA Example

*NOTE:* Keys will be generated internally during the encryption operations.

```sh
uuid=$(cat /proc/sys/kernel/random/uuid)
Expand All @@ -37,20 +47,79 @@ go run crypto-vault-cli.go encrypt-rsa --input data/input.txt --output data/${uu
go run crypto-vault-cli.go decrypt-rsa --input data/${uuid}-encrypted.txt --output data/${uuid}-decrypted.txt --privateKey <your generated private key from previous encryption operation>
```

**RSA with PKCS#11 Example**
#### PKCS#11 encryption and decryption

*NOTE:* Requires RSA keys managed in FIPS-compliant software or hardware trough `pkcs11-tool` or utilize commands in [PKCS#11 key management operations](#pkcs11-key-management-operations):

```sh
TBD
# RSA-PKCS
# Encryption
go run crypto-vault-cli.go encrypt --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --user-pin 5678 --key-type RSA --input-file data/input.txt --output-file data/encrypted-output.enc

# Decryption
go run crypto-vault-cli.go decrypt --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --user-pin 5678 --key-type RSA --input-file data/encrypted-output.enc --output-file data/decrypted-output.txt
```

### Hashing / Verifying signatures
---

**ECDSA Example**
### Signing and Verifying signatures

#### ECDSA Example

*NOTE:* Keys will be generated internally during signature generation operations.

```sh
# Sign a file with a newly generated ECC key pair (internally generated)
go run crypto-vault-cli.go sign-ecc --input data/input.txt --keyDir data

# Verify the signature using the generated public key
go run crypto-vault-cli.go verify-ecc --input data/input.txt --publicKey <your generated public key from previous signing operation> --signature <your generated signature file from previous signing operation>
```

#### PKCS#11 signing and verifying

*NOTE:* Requires RSA or EC keys managed in FIPS-compliant software or hardware trough `pkcs11-tool` or utilize commands in [PKCS#11 key management operations](#pkcs11-key-management-operations):

```sh
# RSA-PSS
# Sign data with a PKCS#11 token
go run crypto-vault-cli.go sign --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --user-pin 5678 --key-type RSA --input-file data/input.txt --output-file data/signature.sig

# Verify the signature using the generated public key from the PKCS#11 token
go run crypto-vault-cli.go verify --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --user-pin 5678 --key-type RSA --data-file data/input.txt --signature-file data/signature.sig

# ECDSA
# Sign data with a PKCS#11 token
go run crypto-vault-cli.go sign --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-ecdsa-key --user-pin 5678 --key-type ECDSA --input-file data/input.txt --output-file data/signature.sig

# Verify the signature using the generated public key from the PKCS#11 token
go run crypto-vault-cli.go verify --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-ecdsa-key --user-pin 5678 --key-type ECDSA --data-file data/input.txt --signature-file data/signature.sig
```

---

### PKCS#11 key management operations

```sh
# Check available slots
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -L
# Initialize a PKCS#11 token
go run crypto-vault-cli.go initialize-token --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --so-pin 1234 --user-pin 5678 --slot "0x0"

# Check if PKCS#11 token is set
go run crypto-vault-cli.go is-token-set --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token

# Check if an object (e.g., key) exists in the PKCS#11 token
go run crypto-vault-cli.go is-object-set --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --user-pin 5678
# Check all keys of a token
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -O --token-label "my-token" --pin 5678

# Adding keys to tokens
# Add an RSA or ECDSA key pair (private and public key) to a PKCS#11 token
go run crypto-vault-cli.go add-key --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --key-type RSA --key-size 2048 --user-pin 5678

# Deleting keys from tokens
# Delete an object (e.g., RSA or ECDSA key) from the PKCS#11 token
go run crypto-vault-cli.go delete-object --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --object-type pubkey --user-pin 5678
go run crypto-vault-cli.go delete-object --module /usr/lib/softhsm/libsofthsm2.so --token-label my-token --object-label my-rsa-key --object-type privkey --user-pin 5678
```
69 changes: 7 additions & 62 deletions cmd/crypto-vault-cli/crypto-vault-cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,75 +9,20 @@ import (
"github.com/spf13/cobra"
)

// Main function
func main() {
var rootCmd = &cobra.Command{Use: "crypto-cli"}
var rootCmd = &cobra.Command{Use: "crypto-vault-cli"}

// AES Commands
var encryptAESFileCmd = &cobra.Command{
Use: "encrypt-aes",
Short: "Encrypt a file using AES",
Run: commands.EncryptAESCmd,
}
encryptAESFileCmd.Flags().StringP("input", "i", "", "Input file path")
encryptAESFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path")
encryptAESFileCmd.Flags().IntP("keySize", "k", 16, "AES key size (default 16 bytes for AES-128)")
encryptAESFileCmd.Flags().StringP("keyDir", "d", "", "Directory to store the encryption key")
rootCmd.AddCommand(encryptAESFileCmd)

var decryptAESFileCmd = &cobra.Command{
Use: "decrypt-aes",
Short: "Decrypt a file using AES",
Run: commands.DecryptAESCmd,
}
decryptAESFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path")
decryptAESFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path")
decryptAESFileCmd.Flags().StringP("symmetricKey", "k", "", "Path to the symmetric key")
rootCmd.AddCommand(decryptAESFileCmd)
commands.InitAESCommands(rootCmd)

// RSA Commands
var encryptRSAFileCmd = &cobra.Command{
Use: "encrypt-rsa",
Short: "Encrypt a file using RSA",
Run: commands.EncryptRSACmd,
}
encryptRSAFileCmd.Flags().StringP("input", "i", "", "Input file path")
encryptRSAFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path")
encryptRSAFileCmd.Flags().StringP("keyDir", "d", "", "Directory to store the encryption key")

rootCmd.AddCommand(encryptRSAFileCmd)
commands.InitRSACommands(rootCmd)

var decryptRSAFileCmd = &cobra.Command{
Use: "decrypt-rsa",
Short: "Decrypt a file using RSA",
Run: commands.DecryptRSACmd,
}
decryptRSAFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path")
decryptRSAFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path")
decryptRSAFileCmd.Flags().StringP("privateKey", "r", "", "Path to RSA private key")
rootCmd.AddCommand(decryptRSAFileCmd)

// ECDSA Command
var signECCMessageCmd = &cobra.Command{
Use: "sign-ecc",
Short: "Sign a message using ECC",
Run: commands.SignECCCmd,
}
// ECDSA Commands
commands.InitECDSACommands(rootCmd)

// Rename the input flag to messageFile for clarity
signECCMessageCmd.Flags().StringP("input", "i", "", "Path to file that needs to be signed")
signECCMessageCmd.Flags().StringP("keyDir", "d", "", "Directory to save generated keys (optional)")
rootCmd.AddCommand(signECCMessageCmd)

var verifyECCSignatureCmd = &cobra.Command{
Use: "verify-ecc",
Short: "Verify a signature using ECC",
Run: commands.VerifyECCCmd,
}
verifyECCSignatureCmd.Flags().StringP("input", "i", "", "Path to ECC public key")
verifyECCSignatureCmd.Flags().StringP("publicKey", "p", "", "The public key used to verify the signature")
verifyECCSignatureCmd.Flags().StringP("signature", "s", "", "Signature to verify (hex format)")
rootCmd.AddCommand(verifyECCSignatureCmd)
// PKCS11 Token Commands
commands.InitPKCS11Commands(rootCmd)

// Execute the root command
if err := rootCmd.Execute(); err != nil {
Expand Down
24 changes: 24 additions & 0 deletions cmd/crypto-vault-cli/internal/commands/aes-commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,27 @@ func DecryptAESCmd(cmd *cobra.Command, args []string) {
}
fmt.Printf("Decrypted data saved to %s\n", outputFile)
}

func InitAESCommands(rootCmd *cobra.Command) {
// AES Commands
var encryptAESFileCmd = &cobra.Command{
Use: "encrypt-aes",
Short: "Encrypt a file using AES",
Run: EncryptAESCmd,
}
encryptAESFileCmd.Flags().StringP("input", "i", "", "Input file path")
encryptAESFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path")
encryptAESFileCmd.Flags().IntP("keySize", "k", 16, "AES key size (default 16 bytes for AES-128)")
encryptAESFileCmd.Flags().StringP("keyDir", "d", "", "Directory to store the encryption key")
rootCmd.AddCommand(encryptAESFileCmd)

var decryptAESFileCmd = &cobra.Command{
Use: "decrypt-aes",
Short: "Decrypt a file using AES",
Run: DecryptAESCmd,
}
decryptAESFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path")
decryptAESFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path")
decryptAESFileCmd.Flags().StringP("symmetricKey", "k", "", "Path to the symmetric key")
rootCmd.AddCommand(decryptAESFileCmd)
}
Loading

0 comments on commit 6c115fa

Please sign in to comment.